%% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[letterpaper,10pt,openany,english]{sphinxmanual}
\ifdefined\pdfpxdimen
   \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen
\fi \sphinxpxdimen=.75bp\relax
\ifdefined\pdfimageresolution
    \pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax
\fi
%% let collapsible pdf bookmarks panel have high depth per default
\PassOptionsToPackage{bookmarksdepth=5}{hyperref}

\PassOptionsToPackage{warn}{textcomp}




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



\setmainfont{FreeSerif}[
  Extension      = .otf,
  UprightFont    = *,
  ItalicFont     = *Italic,
  BoldFont       = *Bold,
  BoldItalicFont = *BoldItalic
]
\setsansfont{FreeSans}[
  Extension      = .otf,
  UprightFont    = *,
  ItalicFont     = *Oblique,
  BoldFont       = *Bold,
  BoldItalicFont = *BoldOblique,
]
\setmonofont{FreeMono}[
  Extension      = .otf,
  UprightFont    = *,
  ItalicFont     = *Oblique,
  BoldFont       = *Bold,
  BoldItalicFont = *BoldOblique,
]



\usepackage[Bjarne]{fncychap}
\usepackage{sphinx}
\sphinxsetup{verbatimwithframe=false}
\fvset{fontsize=\small}
\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}


\usepackage{sphinxmessages}



                 \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{Dec 12, 2021}
\release{8.14.1}
\author{The Coq Development Team}
\newcommand{\sphinxlogo}{\vbox{}}
\renewcommand{\releasename}{Release}
\makeindex
\begin{document}

\pagestyle{empty}
\sphinxmaketitle
\pagestyle{plain}
\sphinxtableofcontents
\pagestyle{normal}
\phantomsection\label{\detokenize{index::doc}}



\chapter{Introduction}
\label{\detokenize{index:introduction}}
\sphinxAtStartPar
This is the reference manual of Coq.  Coq is an interactive theorem
prover.  It lets you formalize mathematical concepts and then helps
you interactively generate machine\sphinxhyphen{}checked proofs of theorems.
Machine checking gives users much more confidence that the proofs are
correct compared to human\sphinxhyphen{}generated and \sphinxhyphen{}checked proofs.  Coq has been
used in a number of flagship verification projects, including the
\sphinxhref{http://compcert.inria.fr/}{CompCert verified C compiler}%
\begin{footnote}[3]\sphinxAtStartFootnote
\sphinxnolinkurl{http://compcert.inria.fr/}
%
\end{footnote}, and has
served to verify the proof of the \sphinxhref{https://github.com/math-comp/fourcolor}{four color theorem}%
\begin{footnote}[4]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/math-comp/fourcolor}
%
\end{footnote} (among many other
mathematical formalizations).

\sphinxAtStartPar
Users generate proofs by entering a series of tactics that constitute
steps in the proof.  There are many built\sphinxhyphen{}in tactics, some of which
are elementary, while others implement complex decision procedures
(such as {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}}, a decision procedure for linear integer
arithmetic).  {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac}}}} and its planned replacement,
{\hyperref[\detokenize{proof-engine/ltac2:ltac2}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac2}}}}, provide languages to define new tactics by
combining existing tactics with looping and conditional constructs.
These permit automation of large parts of proofs and sometimes entire
proofs.  Furthermore, users can add novel tactics or functionality by
creating Coq plugins using OCaml.

\sphinxAtStartPar
The Coq kernel, a small part of Coq, does the final verification that
the tactic\sphinxhyphen{}generated proof is valid.  Usually the tactic\sphinxhyphen{}generated
proof is indeed correct, but delegating proof verification to the
kernel means that even if a tactic is buggy, it won't be able to
introduce an incorrect proof into the system.

\sphinxAtStartPar
Finally, Coq also supports extraction of verified programs to
programming languages such as OCaml and Haskell.  This provides a way
of executing Coq code efficiently and can be used to create verified
software libraries.

\sphinxAtStartPar
To learn Coq, beginners are advised to first start with a tutorial /
book.  Several such tutorials / books are listed at
\sphinxurl{https://coq.inria.fr/documentation}.

\sphinxAtStartPar
This manual is organized in three main parts, plus an appendix:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{The first part presents the specification language of Coq}, that
allows to define programs and state mathematical theorems.
{\hyperref[\detokenize{language/core/index:core-language}]{\sphinxcrossref{\DUrole{std,std-ref}{Core language}}}} presents the language that the kernel of Coq
understands.  {\hyperref[\detokenize{language/extensions/index:extensions}]{\sphinxcrossref{\DUrole{std,std-ref}{Language extensions}}}} presents the richer language, with
notations, implicits, etc. that a user can use and which is
translated down to the language of the kernel by means of an
"elaboration process".

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{The second part presents proof mode}, the central
feature of Coq.  {\hyperref[\detokenize{proofs/writing-proofs/index:writing-proofs}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic proof writing}}}} introduces this interactive
mode and the available proof languages.
{\hyperref[\detokenize{proofs/automatic-tactics/index:automatic-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Automatic solvers and programmable tactics}}}} presents some more advanced tactics, while
{\hyperref[\detokenize{proofs/creating-tactics/index:writing-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Creating new tactics}}}} is about the languages that allow a user to
combine tactics together and develop new ones.

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{The third part shows how to use Coq in practice.}
{\hyperref[\detokenize{using/libraries/index:libraries}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and plugins}}}} presents some of the essential reusable blocks from
the ecosystem and some particularly important extensions such as the
program extraction mechanism.  {\hyperref[\detokenize{using/tools/index:tools}]{\sphinxcrossref{\DUrole{std,std-ref}{Command\sphinxhyphen{}line and graphical tools}}}} documents important
tools that a user needs to build a Coq project.

\item {} 
\sphinxAtStartPar
In the appendix, {\hyperref[\detokenize{appendix/history-and-changes/index:history-and-changes}]{\sphinxcrossref{\DUrole{std,std-ref}{History and recent changes}}}} presents the history of
Coq and changes in recent releases.  This is an important reference
if you upgrade the version of Coq that you use.  The various
\DUrole{xref,std,std-ref}{indexes} are very useful to \sphinxstylestrong{quickly browse the
manual and find what you are looking for.} They are often the main
entry point to the manual.

\end{itemize}

\sphinxAtStartPar
The full table of contents is presented below:

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
\sphinxstylestrong{License}

\sphinxAtStartPar
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.
\end{sphinxadmonition}


\chapter{Specification language}
\label{\detokenize{index:specification-language}}

\section{Core language}
\label{\detokenize{language/core/index:core-language}}\label{\detokenize{language/core/index:id1}}\label{\detokenize{language/core/index::doc}}
\sphinxAtStartPar
At the heart of the Coq proof assistant is the Coq kernel.  While
users have access to a language with many convenient features such as
{\hyperref[\detokenize{user-extensions/syntax-extensions:syntax-extensions-and-notation-scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{notations}}}},
{\hyperref[\detokenize{language/extensions/implicit-arguments:implicitarguments}]{\sphinxcrossref{\DUrole{std,std-ref}{implicit arguments}}}}, etc.  (presented in the
{\hyperref[\detokenize{language/extensions/index:extensions}]{\sphinxcrossref{\DUrole{std,std-ref}{next chapter}}}}), those features are translated into
the core language (the Calculus of Inductive Constructions) that the
kernel understands, which we present here.  Furthermore, while users
can build proofs interactively using tactics (see Chapter
{\hyperref[\detokenize{proofs/writing-proofs/index:writing-proofs}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic proof writing}}}}), the role of these tactics is to incrementally
build a "proof term" which the kernel will verify.  More precisely, a
proof term is a {\hyperref[\detokenize{language/core/basic:term-term}]{\sphinxtermref{\DUrole{xref,std,std-term}{term}}}} of the Calculus of Inductive
Constructions whose {\hyperref[\detokenize{language/core/basic:term-type}]{\sphinxtermref{\DUrole{xref,std,std-term}{type}}}} corresponds to a theorem statement.
The kernel is a type checker which verifies that terms have their
expected types.

\sphinxAtStartPar
This separation between the kernel on one hand and the
{\hyperref[\detokenize{language/extensions/index:extensions}]{\sphinxcrossref{\DUrole{std,std-ref}{elaboration engine}}}} and {\hyperref[\detokenize{proofs/writing-proofs/index:writing-proofs}]{\sphinxcrossref{\DUrole{std,std-ref}{tactics}}}} on the other follows what is known as the \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/index:term-de
Bruijn-criterion}}de
Bruijn criterion} (keeping a small and well delimited trusted code
base within a proof assistant which can be much more complex).  This
separation makes it necessary to trust only a smaller, critical
component (the kernel) instead of the entire system.  In particular,
users may rely on external plugins that provide advanced and complex
tactics without fear of these tactics being buggy, because the kernel
will have to check their output.


\subsection{Basic notions and conventions}
\label{\detokenize{language/core/basic:basic-notions-and-conventions}}\label{\detokenize{language/core/basic::doc}}
\sphinxAtStartPar
This section provides some essential notions and conventions for reading
the manual.

\sphinxAtStartPar
We start by explaining the syntax and lexical conventions used in the
manual.  Then, we present the essential vocabulary necessary to read
the rest of the manual.  Other terms are defined throughout the manual.
The reader may refer to the \DUrole{xref,std,std-ref}{glossary index}
for a complete list of defined terms.  Finally, we describe the various types of
settings that Coq provides.


\subsubsection{Syntax and lexical conventions}
\label{\detokenize{language/core/basic:syntax-and-lexical-conventions}}

\paragraph{Syntax conventions}
\label{\detokenize{language/core/basic:syntax-conventions}}\label{\detokenize{language/core/basic:id1}}
\sphinxAtStartPar
The syntax described in this documentation is equivalent to that
accepted by the Coq parser, but the grammar has been edited
to improve readability and presentation.

\sphinxAtStartPar
In the grammar presented in this manual, the terminal symbols are
black (e.g. \sphinxcode{\sphinxupquote{\DUrole{notation}{forall}}}), whereas the nonterminals are green, italic
and hyperlinked (e.g. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}).  Some syntax is represented
graphically using the following kinds of blocks:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{item}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
An optional item.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{item}\DUrole{notation-sup}{+}}}}}}] \leavevmode
\sphinxAtStartPar
A list of one or more items.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{item}\DUrole{notation-sup}{*}}}}}}] \leavevmode
\sphinxAtStartPar
An optional list of items.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{item}\DUrole{notation-sup}{+}\DUrole{notation-sub}{s}}}}}}] \leavevmode
\sphinxAtStartPar
A list of one or more items separated by "s" (e.g. \sphinxcode{\sphinxupquote{\DUrole{notation}{item$_{\text{1}}$ s item$_{\text{2}}$ s item$_{\text{3}}$}}}).

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{item}\DUrole{notation-sup}{*}\DUrole{notation-sub}{s}}}}}}] \leavevmode
\sphinxAtStartPar
An optional list of items separated by "s".

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{item$_{\text{1}}$}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{item$_{\text{2}}$}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{...}}}}}}] \leavevmode
\sphinxAtStartPar
Alternatives (either \sphinxcode{\sphinxupquote{\DUrole{notation}{item$_{\text{1}}$}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{item$_{\text{2}}$}}} or ...).

\end{description}

\sphinxAtStartPar
\sphinxhref{https://en.wikipedia.org/wiki/Order\_of\_operations}{Precedence levels}%
\begin{footnote}[5]\sphinxAtStartFootnote
\sphinxnolinkurl{https://en.wikipedia.org/wiki/Order\_of\_operations}
%
\end{footnote} that are
implemented in the Coq parser are shown in the documentation by
appending the level to the nonterminal name (as in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}}} or
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}).

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Coq uses an extensible parser.  Plugins and the {\hyperref[\detokenize{user-extensions/syntax-extensions:syntax-extensions-and-notation-scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{notation
system}}}} can extend the
syntax at run time.  Some notations are defined in the {\hyperref[\detokenize{language/coq-library:term-prelude}]{\sphinxtermref{\DUrole{xref,std,std-term}{prelude}}}},
which is loaded by default.  The documented grammar doesn't include
these notations.  Precedence levels not used by the base grammar
are omitted from the documentation, even though they could still be
populated by notations or plugins.

\sphinxAtStartPar
Furthermore, some parsing rules are only activated in certain
contexts ({\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{proof mode}}}},
{\hyperref[\detokenize{user-extensions/syntax-extensions:custom-entries}]{\sphinxcrossref{\DUrole{std,std-ref}{custom entries}}}}...).
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
Given the complexity of these parsing rules, it would be extremely
difficult to create an external program that can properly parse a
Coq document.  Therefore, tool writers are advised to delegate
parsing to Coq, by communicating with it, for instance through
\sphinxhref{https://github.com/ejgallego/coq-serapi}{SerAPI}%
\begin{footnote}[6]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/ejgallego/coq-serapi}
%
\end{footnote}.
\end{sphinxadmonition}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Grammar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Grammar}}}}}




\paragraph{Lexical conventions}
\label{\detokenize{language/core/basic:lexical-conventions}}\label{\detokenize{language/core/basic:id2}}\begin{description}
\item[{Blanks}] \leavevmode
\sphinxAtStartPar
Space, newline and horizontal tab are considered blanks.
Blanks are ignored but they separate tokens.

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

\item[{Identifiers}] \leavevmode
\sphinxAtStartPar
Identifiers, written \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{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 grammar (except that the string \sphinxcode{\sphinxupquote{\_}} is reserved;
it is not a valid identifier):
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-ident}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-first_letter}]{\sphinxcrossref{\DUrole{hole}{first\_letter}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-subsequent_letter}]{\sphinxcrossref{\DUrole{hole}{subsequent\_letter}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-first_letter}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-first_letter}]{\sphinxcrossref{\DUrole{hole}{first\_letter}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{a .. z}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{A .. Z}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\_}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-unicode_letter}]{\sphinxcrossref{\DUrole{hole}{unicode\_letter}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-subsequent_letter}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-subsequent_letter}]{\sphinxcrossref{\DUrole{hole}{subsequent\_letter}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-first_letter}]{\sphinxcrossref{\DUrole{hole}{first\_letter}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-digit}]{\sphinxcrossref{\DUrole{hole}{digit}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\textquotesingle{}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-unicode_id_part}]{\sphinxcrossref{\DUrole{hole}{unicode\_id\_part}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
All characters are meaningful. In particular, identifiers are case\sphinxhyphen{}sensitive.
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-unicode_letter}}\sphinxcode{\sphinxupquote{unicode\_letter}}} non\sphinxhyphen{}exhaustively includes Latin,
Greek, Gothic, Cyrillic, Arabic, Hebrew, Georgian, Hangul, Hiragana
and Katakana characters, CJK ideographs, mathematical letter\sphinxhyphen{}like
symbols and non\sphinxhyphen{}breaking space. \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-unicode_id_part}}\sphinxcode{\sphinxupquote{unicode\_id\_part}}}
non\sphinxhyphen{}exhaustively includes symbols for prime letters and subscripts.

\item[{Numbers}] \leavevmode
\sphinxAtStartPar
Numbers are sequences of digits with an optional fractional part
and exponent, optionally preceded by a minus sign. Hexadecimal numbers
start with \sphinxcode{\sphinxupquote{0x}} or \sphinxcode{\sphinxupquote{0X}}. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bigint}]{\sphinxcrossref{\DUrole{hole}{bigint}}}}}}} are integers;
numbers without fractional nor exponent parts. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}} are non\sphinxhyphen{}negative
integers.  Underscores embedded in the digits are ignored, for example
\sphinxcode{\sphinxupquote{1\_000\_000}} is the same as \sphinxcode{\sphinxupquote{1000000}}.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-number}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-number}]{\sphinxcrossref{\DUrole{hole}{number}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-decnat}]{\sphinxcrossref{\DUrole{hole}{decnat}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{. \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-digit}]{\sphinxcrossref{\DUrole{hole}{digit}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\_}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{e}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{E}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{+}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\sphinxhyphen{}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-decnat}]{\sphinxcrossref{\DUrole{hole}{decnat}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-hexnat}]{\sphinxcrossref{\DUrole{hole}{hexnat}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{. \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-hexdigit}]{\sphinxcrossref{\DUrole{hole}{hexdigit}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\_}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{p}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{P}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{+}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\sphinxhyphen{}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-decnat}]{\sphinxcrossref{\DUrole{hole}{decnat}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-integer}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-natural}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-bigint}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bigint}]{\sphinxcrossref{\DUrole{hole}{bigint}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-bignat}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-decnat}]{\sphinxcrossref{\DUrole{hole}{decnat}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-hexnat}]{\sphinxcrossref{\DUrole{hole}{hexnat}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-decnat}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-decnat}]{\sphinxcrossref{\DUrole{hole}{decnat}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-digit}]{\sphinxcrossref{\DUrole{hole}{digit}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-digit}]{\sphinxcrossref{\DUrole{hole}{digit}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\_}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-digit}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-digit}]{\sphinxcrossref{\DUrole{hole}{digit}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{0 .. 9}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-hexnat}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-hexnat}]{\sphinxcrossref{\DUrole{hole}{hexnat}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{0x}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{0X}} {\hyperref[\detokenize{language/core/basic:grammar-token-hexdigit}]{\sphinxcrossref{\DUrole{hole}{hexdigit}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-hexdigit}]{\sphinxcrossref{\DUrole{hole}{hexdigit}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\_}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-hexdigit}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-hexdigit}]{\sphinxcrossref{\DUrole{hole}{hexdigit}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{0 .. 9}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{a .. f}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{A .. F}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} are limited to the range that fits
into an OCaml integer (63\sphinxhyphen{}bit integers on most architectures).
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bigint}]{\sphinxcrossref{\DUrole{hole}{bigint}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}} have no range limitation.

\sphinxAtStartPar
The {\hyperref[\detokenize{language/coq-library:thecoqlibrary}]{\sphinxcrossref{\DUrole{std,std-ref}{standard library}}}} provides some
{\hyperref[\detokenize{user-extensions/syntax-extensions:id8}]{\sphinxcrossref{\DUrole{std,std-ref}{interpretations}}}} for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-number}]{\sphinxcrossref{\DUrole{hole}{number}}}}}}}. The
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} mechanism offers the user
a way to define custom parsers and printers for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-number}]{\sphinxcrossref{\DUrole{hole}{number}}}}}}}.

\item[{Strings}] \leavevmode
\sphinxAtStartPar
Strings begin and end with \sphinxcode{\sphinxupquote{"}} (double quote).  Use \sphinxcode{\sphinxupquote{""}} to represent
a double quote character within a string.  In the grammar, strings are
identified with \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-string}}\sphinxcode{\sphinxupquote{string}}}.

\sphinxAtStartPar
The {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}} mechanism offers the
user a way to define custom parsers and printers for
{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}.

\item[{Keywords}] \leavevmode
\sphinxAtStartPar
The following character sequences are keywords defined in the main Coq grammar
that cannot be used as identifiers (even when starting Coq with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}noinit}}
command\sphinxhyphen{}line flag):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZus{} Axiom CoFixpoint Definition Fixpoint Hypothesis Parameter Prop
SProp Set Theorem Type Variable as at cofix else end
fix for forall fun if in let match return then where with
\end{sphinxVerbatim}

\sphinxAtStartPar
The following are keywords defined in notations or plugins loaded in the {\hyperref[\detokenize{language/coq-library:term-prelude}]{\sphinxtermref{\DUrole{xref,std,std-term}{prelude}}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
IF by exists exists2 using
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that loading additional modules or plugins may expand the set of reserved
keywords.

\item[{Other tokens}] \leavevmode
\sphinxAtStartPar
The following character sequences are tokens defined in the main Coq grammar
(even when starting Coq with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}noinit}} command\sphinxhyphen{}line flag):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
! \PYGZsh{}[ \PYGZpc{} \PYGZam{} \PYGZsq{} ( () ) * + , \PYGZhy{} \PYGZhy{}\PYGZgt{}
. .( .. ... / : ::= := :\PYGZgt{} ; \PYGZlt{} \PYGZlt{}+ \PYGZlt{}\PYGZhy{} \PYGZlt{}:
\PYGZlt{}\PYGZlt{}: \PYGZlt{}= = =\PYGZgt{} \PYGZgt{} \PYGZgt{}\PYGZhy{}\PYGZgt{} \PYGZgt{}= ? @ @\PYGZob{} [ ] \PYGZus{}
`( `\PYGZob{} \PYGZob{} \PYGZob{}| | \PYGZcb{}
\end{sphinxVerbatim}

\sphinxAtStartPar
The following character sequences are tokens defined in notations or plugins
loaded in the {\hyperref[\detokenize{language/coq-library:term-prelude}]{\sphinxtermref{\DUrole{xref,std,std-term}{prelude}}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
** [= |\PYGZhy{} || \PYGZhy{}\PYGZgt{}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that loading additional modules or plugins may expand the set of defined
tokens.

\sphinxAtStartPar
When multiple tokens match the beginning of a sequence of characters,
the longest matching token is used.
Occasionally you may need to insert spaces to separate tokens.  For example,
if \sphinxcode{\sphinxupquote{\textasciitilde{}}} and \sphinxcode{\sphinxupquote{\textasciitilde{}\textasciitilde{}}} are both defined as tokens, the inputs \sphinxcode{\sphinxupquote{\textasciitilde{} \textasciitilde{}}} and
\sphinxcode{\sphinxupquote{\textasciitilde{}\textasciitilde{}}} generate different tokens, whereas if \sphinxcode{\sphinxupquote{\textasciitilde{}\textasciitilde{}}} is not defined, then the
two inputs are equivalent.

\end{description}


\subsubsection{Essential vocabulary}
\label{\detokenize{language/core/basic:essential-vocabulary}}
\sphinxAtStartPar
This section presents the most essential notions to understand the
rest of the Coq manual: {\hyperref[\detokenize{language/core/basic:term-term}]{\sphinxtermref{\DUrole{xref,std,std-term}{terms}}}} and {\hyperref[\detokenize{language/core/basic:term-type}]{\sphinxtermref{\DUrole{xref,std,std-term}{types}}}} on the one hand, {\hyperref[\detokenize{language/core/basic:term-command}]{\sphinxtermref{\DUrole{xref,std,std-term}{commands}}}} and {\hyperref[\detokenize{language/core/basic:term-tactic}]{\sphinxtermref{\DUrole{xref,std,std-term}{tactics}}}} on the other hand.
\begin{description}
\item[{term\index{term@\spxentry{term}|spxpagem}\phantomsection\label{\detokenize{language/core/basic:term-term}}}] \leavevmode
\sphinxAtStartPar
Terms are the basic expressions of Coq.  Terms can represent
mathematical expressions, propositions and proofs, but also
executable programs and program types.

\sphinxAtStartPar
Here is the top\sphinxhyphen{}level syntax of terms.  Each of the listed
constructs is presented in a dedicated section.  Some of these
constructs (like \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-term_forall_or_fun}]{\sphinxcrossref{\DUrole{hole}{term\_forall\_or\_fun}}}}}}}) are part of the core
language that the kernel of Coq understands and are therefore
described in {\hyperref[\detokenize{language/core/index:core-language}]{\sphinxcrossref{\DUrole{std,std-ref}{this chapter}}}}, while
others (like \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/match:grammar-token-term_if}]{\sphinxcrossref{\DUrole{hole}{term\_if}}}}}}}) are language extensions that are
presented in {\hyperref[\detokenize{language/extensions/index:extensions}]{\sphinxcrossref{\DUrole{std,std-ref}{the next chapter}}}}.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-term_forall_or_fun}]{\sphinxcrossref{\DUrole{hole}{term\_forall\_or\_fun}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-term_let}]{\sphinxcrossref{\DUrole{hole}{term\_let}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/match:grammar-token-term_if}]{\sphinxcrossref{\DUrole{hole}{term\_if}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-term_fix}]{\sphinxcrossref{\DUrole{hole}{term\_fix}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/coinductive:grammar-token-term_cofix}]{\sphinxcrossref{\DUrole{hole}{term\_cofix}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-term100}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-term_cast}]{\sphinxcrossref{\DUrole{hole}{term\_cast}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-term10}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-term_application}]{\sphinxcrossref{\DUrole{hole}{term\_application}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-one_term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-term_explicit}]{\sphinxcrossref{\DUrole{hole}{term\_explicit}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term1}]{\sphinxcrossref{\DUrole{hole}{term1}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-term1}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term1}]{\sphinxcrossref{\DUrole{hole}{term1}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-term_projection}]{\sphinxcrossref{\DUrole{hole}{term\_projection}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-term_scope}]{\sphinxcrossref{\DUrole{hole}{term\_scope}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-term0}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-qualid_annotated}]{\sphinxcrossref{\DUrole{hole}{qualid\_annotated}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-primitive_notations}]{\sphinxcrossref{\DUrole{hole}{primitive\_notations}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/evars:grammar-token-term_evar}]{\sphinxcrossref{\DUrole{hole}{term\_evar}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-term_match}]{\sphinxcrossref{\DUrole{hole}{term\_match}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-term_record}]{\sphinxcrossref{\DUrole{hole}{term\_record}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-term_generalizing}]{\sphinxcrossref{\DUrole{hole}{term\_generalizing}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[}| \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}} | {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} |{]} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_annot}]{\sphinxcrossref{\DUrole{hole}{univ\_annot}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-term_ltac}]{\sphinxcrossref{\DUrole{hole}{term\_ltac}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-qualid_annotated}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-qualid_annotated}]{\sphinxcrossref{\DUrole{hole}{qualid\_annotated}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_annot}]{\sphinxcrossref{\DUrole{hole}{univ\_annot}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Many {\hyperref[\detokenize{language/core/basic:term-command}]{\sphinxtermref{\DUrole{xref,std,std-term}{commands}}}} and {\hyperref[\detokenize{language/core/basic:term-tactic}]{\sphinxtermref{\DUrole{xref,std,std-term}{tactics}}}}
use \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} (in the syntax of their arguments) rather
than \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.  The former need to be enclosed in
parentheses unless they're very simple, such as a single
identifier.  This avoids confusing a space\sphinxhyphen{}separated list of
terms or identifiers with a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-term_application}]{\sphinxcrossref{\DUrole{hole}{term\_application}}}}}}}.
\end{sphinxadmonition}

\item[{type\index{type@\spxentry{type}|spxpagem}\phantomsection\label{\detokenize{language/core/basic:term-type}}}] \leavevmode
\sphinxAtStartPar
To be valid and accepted by the Coq kernel, a term needs an
associated type.  We express this relationship by “\(x\) \sphinxstyleemphasis{of
type} \(T\)”, which we write as “\(x:T\)”.  Informally,
“\(x:T\)” can be thought as “\(x\) \sphinxstyleemphasis{belongs to}
\(T\)”.

\sphinxAtStartPar
The Coq kernel is a type checker: it verifies that a term has
the expected type by applying a set of typing rules (see
{\hyperref[\detokenize{language/cic:id4}]{\sphinxcrossref{\DUrole{std,std-ref}{Typing rules}}}}).  If that's indeed the case, we say that the
term is \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/basic:term-well-typed}}well\sphinxhyphen{}typed}.

\sphinxAtStartPar
A special feature of the Coq language is that types can depend
on terms (we say that the language is \sphinxhref{https://en.wikipedia.org/wiki/Dependent\_type}{dependently\sphinxhyphen{}typed}%
\begin{footnote}[7]\sphinxAtStartFootnote
\sphinxnolinkurl{https://en.wikipedia.org/wiki/Dependent\_type}
%
\end{footnote}).  Because of
this, types and terms share a common syntax.  All types are terms,
but not all terms are types:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-type}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Intuitively, types may be viewed as sets containing terms.  We
say that a type is \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/basic:term-inhabited}}inhabited} if it contains at least one
term (i.e. if we can find a term which is associated with this
type).  We call such terms \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/basic:term-witness}}witnesses}.  Note that deciding
whether a type is inhabited is \sphinxhref{https://en.wikipedia.org/wiki/Undecidable\_problem}{undecidable}%
\begin{footnote}[8]\sphinxAtStartFootnote
\sphinxnolinkurl{https://en.wikipedia.org/wiki/Undecidable\_problem}
%
\end{footnote}.

\sphinxAtStartPar
Formally, types can be used to construct logical foundations for
mathematics alternative to the standard \sphinxhref{https://en.wikipedia.org/wiki/Set\_theory}{"set theory"}%
\begin{footnote}[9]\sphinxAtStartFootnote
\sphinxnolinkurl{https://en.wikipedia.org/wiki/Set\_theory}
%
\end{footnote}: we call such
logical foundations \sphinxhref{https://en.wikipedia.org/wiki/Type\_theory}{"type theories"}%
\begin{footnote}[10]\sphinxAtStartFootnote
\sphinxnolinkurl{https://en.wikipedia.org/wiki/Type\_theory}
%
\end{footnote}.  Coq is based on
the Calculus of Inductive Constructions, which is a particular
instance of type theory.

\item[{sentence\index{sentence@\spxentry{sentence}|spxpagem}\phantomsection\label{\detokenize{language/core/basic:term-sentence}}}] \leavevmode
\sphinxAtStartPar
Coq documents are made of a series of sentences that contain
{\hyperref[\detokenize{language/core/basic:term-command}]{\sphinxtermref{\DUrole{xref,std,std-term}{commands}}}} or {\hyperref[\detokenize{language/core/basic:term-tactic}]{\sphinxtermref{\DUrole{xref,std,std-term}{tactics}}}}, generally
terminated with a period and optionally decorated with
{\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attributes}}}}.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-document}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-document}]{\sphinxcrossref{\DUrole{hole}{document}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-sentence}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-attributes}]{\sphinxcrossref{\DUrole{hole}{attributes}}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-command}]{\sphinxcrossref{\DUrole{hole}{command}}}} .}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-attributes}]{\sphinxcrossref{\DUrole{hole}{attributes}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}} :}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-query_command}]{\sphinxcrossref{\DUrole{hole}{query\_command}}}} .}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-attributes}]{\sphinxcrossref{\DUrole{hole}{attributes}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-toplevel_selector}]{\sphinxcrossref{\DUrole{hole}{toplevel\_selector}}}} :}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} \DUrole{alternative}{\DUrole{alternative-block}{.}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{...}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-control_command}]{\sphinxcrossref{\DUrole{hole}{control\_command}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} syntax supports both simple and compound
{\hyperref[\detokenize{language/core/basic:term-tactic}]{\sphinxtermref{\DUrole{xref,std,std-term}{tactics}}}}.  For example: \sphinxcode{\sphinxupquote{split}} is a simple
tactic while \sphinxcode{\sphinxupquote{split; auto}} combines two simple tactics.

\item[{command\index{command@\spxentry{command}|spxpagem}\phantomsection\label{\detokenize{language/core/basic:term-command}}}] \leavevmode
\sphinxAtStartPar
A \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-command}}\sphinxcode{\sphinxupquote{command}}} can be used to modify the state of a Coq
document, for instance by declaring a new object, or to get
information about the current state.

\sphinxAtStartPar
By convention, command names begin with uppercase letters.
Commands appear in the HTML documentation in blue or gray boxes
after the label "Command".  In the pdf, they appear after the
boldface label "Command:".  Commands are listed in the
\DUrole{xref,std,std-ref}{command\_index}.  Example:
\index{Comments (command)@\spxentry{Comments}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Comments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Comments~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
Prints "Comments ok" and does not change
the state of the document.

\end{fulllineitems}\end{savenotes}


\item[{tactic\index{tactic@\spxentry{tactic}|spxpagem}\phantomsection\label{\detokenize{language/core/basic:term-tactic}}}] \leavevmode
\sphinxAtStartPar
A \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-tactic}}\sphinxcode{\sphinxupquote{tactic}}} specifies how to transform the current proof state as a
step in creating a proof.  They are syntactically valid only when
Coq is in {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-proof-mode}]{\sphinxtermref{\DUrole{xref,std,std-term}{proof mode}}}}, such as after a {\hyperref[\detokenize{language/core/definitions:coq:cmd.Theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} command
and before any subsequent proof\sphinxhyphen{}terminating command such as
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}.  See {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof mode}}}} for more on proof mode.

\sphinxAtStartPar
By convention, tactic names begin with lowercase letters.  Tactic
appear in the HTML documentation in blue or gray boxes after the
label "Tactic".  In the pdf, they appear after the boldface label
"Tactic:".  Tactics are listed in the \DUrole{xref,std,std-ref}{tactic\_index}.

\end{description}


\subsubsection{Settings}
\label{\detokenize{language/core/basic:settings}}
\sphinxAtStartPar
There are several mechanisms for changing the behavior of Coq.  The
{\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}} mechanism is used to modify the behavior of a single
{\hyperref[\detokenize{language/core/basic:term-sentence}]{\sphinxtermref{\DUrole{xref,std,std-term}{sentence}}}}.  The {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}, {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} and {\hyperref[\detokenize{language/core/basic:term-table}]{\sphinxtermref{\DUrole{xref,std,std-term}{table}}}}
mechanisms are used to modify the behavior of Coq more globally in a
document or project.


\paragraph{Attributes}
\label{\detokenize{language/core/basic:attributes}}\label{\detokenize{language/core/basic:id3}}
\sphinxAtStartPar
An \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/basic:term-attribute}}attribute} modifies the behavior of a single sentence.
Syntactically, most commands and tactics can be decorated with
attributes (cf. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}), but attributes not supported by the
command or tactic will trigger {\hyperref[\detokenize{language/core/basic:coq:warn.This-command-does-not-support-this-attribute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{This command does not support
this attribute}}}}}.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-attributes}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-attributes}]{\sphinxcrossref{\DUrole{hole}{attributes}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\#{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-attribute}]{\sphinxcrossref{\DUrole{hole}{attribute}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} {]}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-attribute}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-attribute}]{\sphinxcrossref{\DUrole{hole}{attribute}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-attr_value}]{\sphinxcrossref{\DUrole{hole}{attr\_value}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-attr_value}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-attr_value}]{\sphinxcrossref{\DUrole{hole}{attr\_value}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{= {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{= {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-attribute}]{\sphinxcrossref{\DUrole{hole}{attribute}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-legacy_attr}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Local}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Global}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Polymorphic}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Monomorphic}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Cumulative}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{NonCumulative}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Private}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Program}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The order of top\sphinxhyphen{}level attributes doesn't affect their meaning.  \sphinxcode{\sphinxupquote{\#{[}foo,bar{]}}}, \sphinxcode{\sphinxupquote{\#{[}bar,foo{]}}},
\sphinxcode{\sphinxupquote{\#{[}foo{]}\#{[}bar{]}}} and \sphinxcode{\sphinxupquote{\#{[}bar{]}\#{[}foo{]}}} are equivalent.

\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/basic:term-boolean-attribute}}Boolean attributes} take the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{attr}}$}}}}\DUrole{repeat-wrapper}{\DUrole{repeat}{= \DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}}}}}.
When the \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}}} value is omitted, the default is \sphinxcode{\sphinxupquote{\DUrole{notation}{yes}}}.

\sphinxAtStartPar
The legacy attributes (\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}) provide an older, alternate syntax
for certain attributes.  They are equivalent to new attributes as follows:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
Legacy attribute
&\sphinxstyletheadfamily 
\sphinxAtStartPar
New attribute
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Local}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Global}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Polymorphic}}, \sphinxcode{\sphinxupquote{Monomorphic}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Cumulative}}, \sphinxcode{\sphinxupquote{NonCumulative}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative)}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Private}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/variants:coq:attr.private(matching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{private(matching)}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Program}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\sphinxAtStartPar
Attributes appear in the HTML documentation in blue or gray boxes
after the label "Attribute".  In the pdf, they appear after the
boldface label "Attribute:".  Attributes are listed in the
\DUrole{xref,std,std-ref}{attribute\_index}.
\index{This command does not support this attribute (warning)@\spxentry{This command does not support this attribute}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:warn.This-command-does-not-support-this-attribute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{This~command~does~not~support~this~attribute:~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\sphinxAtStartPar
This warning is configured to behave as an error by default.  You
may turn it into a normal warning by using the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Warnings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Warnings}}}}} option:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Warnings} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{unsupported\PYGZhy{}attributes}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\PYG{o}{\PYGZsh{}}\PYG{o}{[} \PYG{n}{foo} \PYG{o}{]} \PYG{n}{Comments}\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}{18}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZsh{}}\PYG{o}{[} \PYG{n}{foo} \PYG{o}{]} \PYG{n}{Comments}\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{n}{Warning}\PYG{o}{:} \PYG{n}{This} \PYG{n}{command} \PYG{n}{does} \PYG{n}{not} \PYG{n}{support} \PYG{n}{this} \PYG{n}{attribute}\PYG{o}{:} \PYG{n}{foo}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{unsupported}\PYG{o}{\PYGZhy{}}\PYG{n}{attributes}\PYG{o}{,}\PYG{n}{parsing}\PYG{o}{]}
\end{sphinxVerbatim}

\end{fulllineitems}\end{savenotes}



\paragraph{Flags, Options and Tables}
\label{\detokenize{language/core/basic:flags-options-and-tables}}\label{\detokenize{language/core/basic:flags-options-tables}}
\sphinxAtStartPar
The following types of settings can be used to change the behavior of Coq in
subsequent commands and tactics (see {\hyperref[\detokenize{language/core/basic:set-unset-scope-qualifiers}]{\sphinxcrossref{\DUrole{std,std-ref}{Locality attributes supported by Set and Unset}}}} for a
more precise description of the scope of these settings):
\begin{itemize}
\item {} 
\sphinxAtStartPar
A \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/basic:term-flag}}flag} has a boolean value, such as {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}}.

\item {} 
\sphinxAtStartPar
An \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/basic:term-option}}option} generally has a numeric or string value, such as {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:opt.Firstorder-Depth}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Firstorder Depth}}}}}.

\item {} 
\sphinxAtStartPar
A \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/basic:term-table}}table} contains a set of {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}s or {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}s.

\item {} 
\sphinxAtStartPar
In addition, some commands provide settings, such as {\hyperref[\detokenize{addendum/extraction:coq:cmd.Extraction-Language}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Language}}}}}.

\end{itemize}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/basic:grammar-token-setting_name}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\begin{quote}

\sphinxAtStartPar
Flags, options and tables are identified by a series of
identifiers.  By convention, each of the identifiers start with an
initial capital letter.
\end{quote}

\sphinxAtStartPar
Flags, options and tables appear in the HTML documentation in blue or
gray boxes after the labels "Flag", "Option" and "Table".  In the pdf,
they appear after a boldface label.  They are listed in the
\DUrole{xref,std,std-ref}{options\_index}.
\index{Set (command)@\spxentry{Set}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Set}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Set~{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is a flag, no value may be provided; the flag
is set to on.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is an option, a value of the appropriate type
must be provided; the option is set to the specified value.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}}, {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} and {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}} attributes.
They are described {\hyperref[\detokenize{language/core/basic:set-unset-scope-qualifiers}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.
\index{There is no flag or option with this name: ""‘setting\_name’"" (warning)@\spxentry{There is no flag or option with this name: ""‘setting\_name’""}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:warn.There-is-no-flag-or-option-with-this-name:-"_u2018setting_name_u2019"}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{There~is~no~flag~or~option~with~this~name:~"{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}".}}}}
\sphinxAtStartPar
This warning message can be raised by {\hyperref[\detokenize{language/core/basic:coq:cmd.Set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Set}}}}} and
{\hyperref[\detokenize{language/core/basic:coq:cmd.Unset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unset}}}}} when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is unknown.  It is a
warning rather than an error because this helps library authors
produce Coq code that is compatible with several Coq versions.
To preserve the same behavior, they may need to set some
compatibility flags or options that did not exist in previous
Coq versions.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Unset (command)@\spxentry{Unset}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Unset}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unset~{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is a flag, it is set to off.  If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is an option, it is
set to its default value.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}}, {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} and {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}} attributes.
They are described {\hyperref[\detokenize{language/core/basic:set-unset-scope-qualifiers}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\end{fulllineitems}\end{savenotes}

\index{Add (command)@\spxentry{Add}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Add}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Adds the specified values to the table \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Remove (command)@\spxentry{Remove}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Remove}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Remove~{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Removes the specified value from the table \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Test (command)@\spxentry{Test}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Test}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Test~{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{for~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is a flag or option, prints its current value.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is a table: if the \sphinxcode{\sphinxupquote{for}} clause is specified, reports
whether the table contains each specified value, otherwise this is equivalent to
{\hyperref[\detokenize{language/core/basic:coq:cmd.Print-Table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Table}}}}}.  The \sphinxcode{\sphinxupquote{for}} clause is not valid for flags and options.
\index{There is no flag, option or table with this name: ""‘setting\_name’"" (error)@\spxentry{There is no flag, option or table with this name: ""‘setting\_name’""}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:exn.There-is-no-flag,-option-or-table-with-this-name:-"_u2018setting_name_u2019"}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{There~is~no~flag,~option~or~table~with~this~name:~"{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}".}}}}
\sphinxAtStartPar
This error message is raised when calling the {\hyperref[\detokenize{language/core/basic:coq:cmd.Test}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Test}}}}}
command (without the \sphinxcode{\sphinxupquote{for}} clause), or the {\hyperref[\detokenize{language/core/basic:coq:cmd.Print-Table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Table}}}}}
command, for an unknown \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{There is no qualid\sphinxhyphen{}valued table with this name: ""‘setting\_name’"" (error)@\spxentry{There is no qualid\sphinxhyphen{}valued table with this name: ""‘setting\_name’""}\spxextra{error}}\index{There is no string\sphinxhyphen{}valued table with this name: ""‘setting\_name’"" (error)@\spxentry{There is no string\sphinxhyphen{}valued table with this name: ""‘setting\_name’""}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:exn.There-is-no-qualid-valued-table-with-this-name:-"_u2018setting_name_u2019"}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{There~is~no~qualid\sphinxhyphen{}valued~table~with~this~name:~"{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}".}}}}\phantomsection\label{\detokenize{language/core/basic:coq:exn.There-is-no-string-valued-table-with-this-name:-"_u2018setting_name_u2019"}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{There~is~no~string\sphinxhyphen{}valued~table~with~this~name:~"{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}".}}}}
\sphinxAtStartPar
These error messages are raised when calling the {\hyperref[\detokenize{language/core/basic:coq:cmd.Add}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add}}}}} or
{\hyperref[\detokenize{language/core/basic:coq:cmd.Remove}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove}}}}} commands, or the {\hyperref[\detokenize{language/core/basic:coq:cmd.Test}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Test}}}}} command with the
\sphinxcode{\sphinxupquote{for}} clause, if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is unknown or does not have
the right type.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Print Options (command)@\spxentry{Print Options}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Print-Options}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Options}}}}
\sphinxAtStartPar
Prints the current value of all flags and options, and the names of all tables.

\end{fulllineitems}\end{savenotes}

\index{Print Table (command)@\spxentry{Print Table}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Print-Table}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Table~{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}}}
\sphinxAtStartPar
Prints the values in the table \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Print Tables (command)@\spxentry{Print Tables}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/basic:coq:cmd.Print-Tables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Tables}}}}
\sphinxAtStartPar
A synonym for {\hyperref[\detokenize{language/core/basic:coq:cmd.Print-Options}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Options}}}}}.

\end{fulllineitems}\end{savenotes}



\subparagraph{Locality attributes supported by \sphinxstyleliteralintitle{\sphinxupquote{Set}} and \sphinxstyleliteralintitle{\sphinxupquote{Unset}}}
\label{\detokenize{language/core/basic:locality-attributes-supported-by-set-and-unset}}\label{\detokenize{language/core/basic:set-unset-scope-qualifiers}}
\sphinxAtStartPar
The {\hyperref[\detokenize{language/core/basic:coq:cmd.Set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Set}}}}} and {\hyperref[\detokenize{language/core/basic:coq:cmd.Unset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unset}}}}} commands support the mutually
exclusive {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}}, {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}} and {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} locality
attributes (or the \sphinxcode{\sphinxupquote{Local}}, \sphinxcode{\sphinxupquote{Export}} or \sphinxcode{\sphinxupquote{Global}} prefixes).

\sphinxAtStartPar
If no attribute is specified, the original value of the flag or option
is restored at the end of the current module but it is \sphinxstyleemphasis{not} restored
at the end of the current section.

\sphinxAtStartPar
Newly opened modules and sections inherit the current settings.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
We discourage using the {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} locality attribute with the
{\hyperref[\detokenize{language/core/basic:coq:cmd.Set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Set}}}}} and {\hyperref[\detokenize{language/core/basic:coq:cmd.Unset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unset}}}}} commands.  If your goal is to define
project\sphinxhyphen{}wide settings, you should rather use the command\sphinxhyphen{}line
arguments \sphinxcode{\sphinxupquote{\sphinxhyphen{}set}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}unset}} for setting flags and options
(see {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{By command line options}}}}).
\end{sphinxadmonition}

\index{Set (sort)@\spxentry{Set}\spxextra{sort}}\index{SProp@\spxentry{SProp}}\index{Prop@\spxentry{Prop}}\index{Type@\spxentry{Type}}\ignorespaces 

\subsection{Sorts}
\label{\detokenize{language/core/sorts:sorts}}\label{\detokenize{language/core/sorts:index-0}}\label{\detokenize{language/core/sorts:id1}}\label{\detokenize{language/core/sorts::doc}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/sorts:grammar-token-sort}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Set}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Prop}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{SProp}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Type}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Type @\{ \_ \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Type @\{ {\hyperref[\detokenize{language/core/sorts:grammar-token-universe}]{\sphinxcrossref{\DUrole{hole}{universe}}}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/sorts:grammar-token-universe}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/sorts:grammar-token-universe}]{\sphinxcrossref{\DUrole{hole}{universe}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{max ( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/sorts:grammar-token-universe_expr}]{\sphinxcrossref{\DUrole{hole}{universe\_expr}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/sorts:grammar-token-universe_expr}]{\sphinxcrossref{\DUrole{hole}{universe\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/sorts:grammar-token-universe_expr}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/sorts:grammar-token-universe_expr}]{\sphinxcrossref{\DUrole{hole}{universe\_expr}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-universe_name}]{\sphinxcrossref{\DUrole{hole}{universe\_name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{+ {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The types of types are called \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/sorts:term-sort}}sorts}.

\sphinxAtStartPar
All sorts have a type and there is an infinite well\sphinxhyphen{}founded typing
hierarchy of sorts whose base sorts are \(\SProp\), \(\Prop\)
and \(\Set\).

\sphinxAtStartPar
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\)
{\hyperref[\detokenize{language/core/basic:term-witness}]{\sphinxtermref{\DUrole{xref,std,std-term}{witnesses}}}} the fact that \(M\) is
provable. An object of type \(\Prop\) is called a \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/sorts:term-proposition}}proposition}.
We denote propositions by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}.
This constitutes a semantic subclass of the syntactic class \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\sphinxAtStartPar
The sort \(\SProp\) is like \(\Prop\) but the propositions in
\(\SProp\) are known to have irrelevant proofs (all proofs are
equal). Objects of type \(\SProp\) are called
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/sorts:term-strict-proposition}}strict propositions}.
See {\hyperref[\detokenize{addendum/sprop:sprop}]{\sphinxcrossref{\DUrole{std,std-ref}{SProp (proof irrelevant propositions)}}}} for information about using
\(\SProp\), and {[}\hyperlink{cite.zebibliography:id21}{GCST19}{]} for meta theoretical
considerations.

\sphinxAtStartPar
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.
We denote specifications (program types) by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}}}}}.
This constitutes a semantic subclass of the syntactic class \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\sphinxAtStartPar
\(\SProp\), \(\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 {[}\hyperlink{cite.zebibliography:id11}{Coq86}{]}, the language of
CIC has infinitely many sorts. There are, in addition to the base sorts,
a hierarchy of universes \(\Type(i)\) for any integer \(i ≥ 1\).

\sphinxAtStartPar
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.

\sphinxAtStartPar
Formally, we call \(\Sort\) the set of sorts which is defined by:
\begin{equation*}
\begin{split}\Sort \equiv \{\SProp,\Prop,\Set,\Type(i)\;|\; i~∈ ℕ\}\end{split}
\end{equation*}
\sphinxAtStartPar
Their properties, such as \(\Prop:\Type(1)\), \(\Set:\Type(1)\), and
\(\Type(i):\Type(i+1)\), are described in {\hyperref[\detokenize{language/cic:subtyping-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Subtyping rules}}}}.

\sphinxAtStartPar
The user does not have to mention explicitly the index \(i\) when
referring to the universe \(\Type(i)\). One only writes \sphinxcode{\sphinxupquote{Type}}. The system
itself generates for each instance of \sphinxcode{\sphinxupquote{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/core/sorts:implementation-issues}}
\sphinxAtStartPar
\sphinxstylestrong{Implementation issues} In practice, the Type hierarchy is
implemented using algebraic universes.
An \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/sorts:term-algebraic-universe}}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/core/inductive:well-formed-inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Well\sphinxhyphen{}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 {\hyperref[\detokenize{addendum/universe-polymorphism:coq:exn.Universe-inconsistency}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe inconsistency}}}}} error.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{addendum/universe-polymorphism:printing-universes}]{\sphinxcrossref{\DUrole{std,std-ref}{Printing universes}}}}, {\hyperref[\detokenize{addendum/universe-polymorphism:explicit-universes}]{\sphinxcrossref{\DUrole{std,std-ref}{Explicit Universes}}}}.




\subsection{Functions and assumptions}
\label{\detokenize{language/core/assumptions:functions-and-assumptions}}\label{\detokenize{language/core/assumptions::doc}}

\subsubsection{Binders}
\label{\detokenize{language/core/assumptions:binders}}\label{\detokenize{language/core/assumptions:id1}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-open_binders}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-name}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-binder}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-implicit_binders}]{\sphinxcrossref{\DUrole{hole}{implicit\_binders}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-generalizing_binder}]{\sphinxcrossref{\DUrole{hole}{generalizing\_binder}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} | {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\textquotesingle{} {\hyperref[\detokenize{language/core/variants:grammar-token-pattern0}]{\sphinxcrossref{\DUrole{hole}{pattern0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/core/basic: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}{)}}}.

\sphinxAtStartPar
Some constructions allow the binding of a variable to value. This is
called a “let\sphinxhyphen{}binder”. The entry \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}} of the grammar accepts
either an assumption binder as defined above or a let\sphinxhyphen{}binder. The notation in
the latter case is \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}. In a let\sphinxhyphen{}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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}.

\sphinxAtStartPar
Lists of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}}s 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}{=>} \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}{=>} \DUrole{name}{t}}}).

\index{fun@\spxentry{fun}}\ignorespaces 
\index{forall@\spxentry{forall}}\ignorespaces 

\subsubsection{Functions (fun) and function types (forall)}
\label{\detokenize{language/core/assumptions:functions-fun-and-function-types-forall}}\label{\detokenize{language/core/assumptions:index-1}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-term_forall_or_fun}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-term_forall_or_fun}]{\sphinxcrossref{\DUrole{hole}{term\_forall\_or\_fun}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} , {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{fun {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{fun {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} defines the
\sphinxstyleemphasis{abstraction} of the variable \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, of type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}, over the term
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. It denotes a function of the variable \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} that evaluates to
the expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} (e.g. \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{A} \DUrole{operator}{=>} \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/core/assumptions:binders}]{\sphinxcrossref{\DUrole{std,std-ref}{Binders}}}}. Functions over
several variables are equivalent to an iteration of one\sphinxhyphen{}variable
functions. For instance the expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
denotes the same function as \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{fun {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} =>}\DUrole{notation-sup}{+}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. If
a let\sphinxhyphen{}binder occurs in
the list of binders, it is expanded to a let\sphinxhyphen{}in definition (see
Section {\hyperref[\detokenize{language/core/definitions:let-in}]{\sphinxcrossref{\DUrole{std,std-ref}{Let\sphinxhyphen{}in definitions}}}}).

\sphinxAtStartPar
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{forall {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}, {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} denotes the
\sphinxstyleemphasis{product} of the variable \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} of type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}, over the term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{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\sphinxhyphen{}variable
products. Note that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is intended to be a type.

\sphinxAtStartPar
If the variable \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} occurs in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{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).

\sphinxAtStartPar
Non dependent product types have a special notation: \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{\sphinxhyphen{}>} \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{Function application}
\label{\detokenize{language/core/assumptions:function-application}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-term_application}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-term_application}]{\sphinxcrossref{\DUrole{hole}{term\_application}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term1}]{\sphinxcrossref{\DUrole{hole}{term1}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{@ {\hyperref[\detokenize{language/core/basic:grammar-token-qualid_annotated}]{\sphinxcrossref{\DUrole{hole}{qualid\_annotated}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term1}]{\sphinxcrossref{\DUrole{hole}{term1}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-arg}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term1}]{\sphinxcrossref{\DUrole{hole}{term1}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{fun}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} denotes applying the function \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{fun}}$}}}}}}} to {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{fun}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{i}}$}}}}}\DUrole{notation-sup}{+}}}}} denotes applying
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{fun}}$}}}}}}} to the arguments \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{i}}$}}}}}}}.  It is
equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{( … ( {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{fun}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} ) … ) {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{n}}$}}}}}}}:
associativity is to the left.

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


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

\phantomsection\label{\detokenize{language/core/assumptions:axiom}}\index{Axiom (command)@\spxentry{Axiom}\spxextra{command}}\index{Axioms (command)@\spxentry{Axioms}\spxextra{command}}\index{Conjecture (command)@\spxentry{Conjecture}\spxextra{command}}\index{Conjectures (command)@\spxentry{Conjectures}\spxextra{command}}\index{Hypothesis (command)@\spxentry{Hypothesis}\spxextra{command}}\index{Hypotheses (command)@\spxentry{Hypotheses}\spxextra{command}}\index{Parameter (command)@\spxentry{Parameter}\spxextra{command}}\index{Parameters (command)@\spxentry{Parameters}\spxextra{command}}\index{Variable (command)@\spxentry{Variable}\spxextra{command}}\index{Variables (command)@\spxentry{Variables}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Axiom}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Axioms}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Conjecture}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Conjectures}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Hypothesis}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Hypotheses}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Parameter}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Parameters}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Variable}}\phantomsection\label{\detokenize{language/core/assumptions:coq:cmd.Variables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-assumption_token}]{\sphinxcrossref{\DUrole{hole}{assumption\_token}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{Inline~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~)}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}~\DUrole{alternative}{\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{(~{\hyperref[\detokenize{language/core/assumptions:grammar-token-assumpt}]{\sphinxcrossref{\DUrole{hole}{assumpt}}}}~)}\DUrole{notation-sup}{+}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-assumpt}]{\sphinxcrossref{\DUrole{hole}{assumpt}}}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-assumption_token}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-assumption_token}]{\sphinxcrossref{\DUrole{hole}{assumption\_token}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Axiom}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Axioms}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Conjecture}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Conjectures}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Parameter}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Parameters}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Hypothesis}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Hypotheses}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Variable}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Variables}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-assumpt}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-assumpt}]{\sphinxcrossref{\DUrole{hole}{assumpt}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}}\DUrole{notation-sup}{+}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-of_type}]{\sphinxcrossref{\DUrole{hole}{of\_type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-ident_decl}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_decl}]{\sphinxcrossref{\DUrole{hole}{univ\_decl}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/assumptions:grammar-token-of_type}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-of_type}]{\sphinxcrossref{\DUrole{hole}{of\_type}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{:}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{:>}} {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
These commands bind one or more \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}(s) to specified \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}(s) as their specifications in
the global environment. The fact asserted by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} (or, equivalently, the existence
of an object of this type) is accepted as a postulate.  They accept the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute.

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/assumptions:coq:cmd.Axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}}, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Conjecture}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Conjecture}}}}}, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Parameter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Parameter}}}}} and their plural forms
are equivalent.  They can take the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}},
which makes the defined \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}s accessible by {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} and its variants
only through their fully qualified names.

\sphinxAtStartPar
Similarly, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Hypothesis}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hypothesis}}}}}, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}} and their plural forms are equivalent.  Outside
of a section, these are equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{Local Parameter}}}.  Inside a section, the
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}s defined are only accessible within the section.  When the current section
is closed, the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}(s) become undefined and every object depending on them will be explicitly
parameterized (i.e., the variables are \sphinxstyleemphasis{discharged}).  See Section {\hyperref[\detokenize{language/core/sections:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{:>}}}}] \leavevmode
\sphinxAtStartPar
If specified, {\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident\_decl}}}}} is automatically
declared as a coercion to the class of its type.  See {\hyperref[\detokenize{addendum/implicit-coercions:coercions}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit Coercions}}}}.

\end{description}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{Inline}}} clause is only relevant inside functors.  See {\hyperref[\detokenize{language/core/modules:coq:cmd.Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module}}}}}.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example: Simple assumptions}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{X} \PYG{n}{Y} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{o}{(}\PYG{n}{R} \PYG{o}{:} \PYG{n}{X} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{o}{:} \PYG{n}{Y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{X} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{R\PYGZus{}S\PYGZus{}inv} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{R} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{S} \PYG{n}{y} \PYG{n}{x}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{‘ident’ already exists. (Axiom) (error)@\spxentry{‘ident’ already exists. (Axiom)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/assumptions:coq:exn._u2018ident_u2019-already-exists.-(Axiom)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘ident’ is declared as a local axiom (warning)@\spxentry{‘ident’ is declared as a local axiom}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/assumptions:coq:warn._u2018ident_u2019-is-declared-as-a-local-axiom}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~declared~as~a~local~axiom}}}}
\sphinxAtStartPar
Warning generated when using {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}} or its equivalent
instead of \sphinxcode{\sphinxupquote{\DUrole{notation}{Local Parameter}}} or its equivalent.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
We advise using the commands {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}}, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Conjecture}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Conjecture}}}}} and
{\hyperref[\detokenize{language/core/assumptions:coq:cmd.Hypothesis}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hypothesis}}}}} (and their plural forms) for logical postulates (i.e. when
the assertion \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} is of sort \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}), and to use the commands
{\hyperref[\detokenize{language/core/assumptions:coq:cmd.Parameter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Parameter}}}}} and {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}} (and their plural forms) in other cases
(corresponding to the declaration of an abstract object of the given type).
\end{sphinxadmonition}


\subsection{Definitions}
\label{\detokenize{language/core/definitions:definitions}}\label{\detokenize{language/core/definitions::doc}}
\index{let ... := ... (term)@\spxentry{let ... := ...}\spxextra{term}}\ignorespaces 

\subsubsection{Let\sphinxhyphen{}in definitions}
\label{\detokenize{language/core/definitions:let-in-definitions}}\label{\detokenize{language/core/definitions:let-in}}\label{\detokenize{language/core/definitions:index-0}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/definitions:grammar-token-term_let}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-term_let}]{\sphinxcrossref{\DUrole{hole}{term\_let}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/match:grammar-token-destructuring_let}]{\sphinxcrossref{\DUrole{hole}{destructuring\_let}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} represents the local binding of
the variable \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} to the value \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}} in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} is an abbreviation
for \sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}}.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
Extensions of the \sphinxcode{\sphinxupquote{let ... in ...}} syntax are described in
{\hyperref[\detokenize{language/extensions/match:irrefutable-patterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Irrefutable patterns: the destructuring let variants}}}}.



\index{... : ... (type cast)@\spxentry{... : ...}\spxextra{type cast}}\index{... <: ...@\spxentry{... <: ...}}\index{... <<: ...@\spxentry{... <<: ...}}\ignorespaces 

\subsubsection{Type cast}
\label{\detokenize{language/core/definitions:type-cast}}\label{\detokenize{language/core/definitions:index-1}}\label{\detokenize{language/core/definitions:id1}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/definitions:grammar-token-term_cast}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-term_cast}]{\sphinxcrossref{\DUrole{hole}{term\_cast}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}} <: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}} <<: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} is a type cast expression. It enforces
the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}}}}} to be \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}} <: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} specifies that the virtual machine will be used
to type check that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}}}}} has type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} (see {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}}).

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}} <<: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} specifies that compilation to OCaml will be used
to type check that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term10}]{\sphinxcrossref{\DUrole{hole}{term10}}}}}}} has type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} (see {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}).


\subsubsection{Top\sphinxhyphen{}level definitions}
\label{\detokenize{language/core/definitions:top-level-definitions}}\label{\detokenize{language/core/definitions:gallina-definitions}}
\sphinxAtStartPar
Definitions extend the global environment by associating 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.

\sphinxAtStartPar
The operation of unfolding a name into its definition is called
{\hyperref[\detokenize{language/core/conversion:term-delta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{delta\sphinxhyphen{}reduction}}}}.
A definition is accepted by the system if and only if the defined term is
well\sphinxhyphen{}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
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/definitions:term-constant}}constant} and the term it refers to is its \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/definitions:term-body}}body}. A definition has
a type, which is the type of its {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}}.

\sphinxAtStartPar
A formal presentation of constants and environments is given in
Section {\hyperref[\detokenize{language/cic:id4}]{\sphinxcrossref{\DUrole{std,std-ref}{Typing rules}}}}.
\index{Definition (command)@\spxentry{Definition}\spxextra{command}}\index{Example (command)@\spxentry{Example}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Definition}}\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Example}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Definition}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Example}}~{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~{\hyperref[\detokenize{language/core/definitions:grammar-token-def_body}]{\sphinxcrossref{\DUrole{hole}{def\_body}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/definitions:grammar-token-def_body}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-def_body}]{\sphinxcrossref{\DUrole{hole}{def\_body}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} := \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/definitions:grammar-token-reduce}]{\sphinxcrossref{\DUrole{hole}{reduce}}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/definitions:grammar-token-reduce}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-reduce}]{\sphinxcrossref{\DUrole{hole}{reduce}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Eval {\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}} in}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
These commands bind \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to the name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in the global environment,
provided that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is well\sphinxhyphen{}typed.  They can take the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}},
which makes the defined \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} accessible by {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} and its variants
only through their fully qualified names.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-reduce}]{\sphinxcrossref{\DUrole{hole}{reduce}}}}}}} is present then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is bound to the result of the specified
computation on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\sphinxAtStartPar
These commands also support the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}},
{\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} (see {\hyperref[\detokenize{addendum/program:program-definition}]{\sphinxcrossref{\DUrole{std,std-ref}{Program Definition}}}}), {\hyperref[\detokenize{language/extensions/canonical:coq:attr.canonical}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{canonical}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(universes)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(universes)}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(guard)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(guard)}}}}}, and
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:attr.using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{using}}}}} attributes.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is omitted, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} is required and Coq enters proof mode.
This can be used to define a term incrementally, in particular by relying on the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic.
In this case, the proof should be terminated with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}} in order to define a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}}
for which the computational behavior is relevant.  See {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Entering and exiting proof mode}}}}.

\sphinxAtStartPar
The form \sphinxcode{\sphinxupquote{\DUrole{notation}{Definition {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} checks that the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
is definitionally equal to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}, and registers \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} as being of type
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}, and bound to value \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\sphinxAtStartPar
The form \sphinxcode{\sphinxupquote{\DUrole{notation}{Definition {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{Definition {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}, {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} := fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}.


\index{‘ident’ already exists. (Definition) (error)@\spxentry{‘ident’ already exists. (Definition)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/definitions:coq:exn._u2018ident_u2019-already-exists.-(Definition)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
\end{fulllineitems}\end{savenotes}

\index{The term ‘term’ has type ‘type’ while it is expected to have type ‘type’' (error)@\spxentry{The term ‘term’ has type ‘type’ while it is expected to have type ‘type’'}\spxextra{error}}

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


\end{fulllineitems}\end{savenotes}



\subsubsection{Assertions and proofs}
\label{\detokenize{language/core/definitions:assertions-and-proofs}}\label{\detokenize{language/core/definitions:assertions}}
\sphinxAtStartPar
An assertion states a proposition (or a type) for which the proof (or an
inhabitant of the type) is interactively built using {\hyperref[\detokenize{language/core/basic:term-tactic}]{\sphinxtermref{\DUrole{xref,std,std-term}{tactics}}}}.
Assertions cause Coq to enter {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-proof-mode}]{\sphinxtermref{\DUrole{xref,std,std-term}{proof mode}}}} (see {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof mode}}}}).
Common tactics are described in the {\hyperref[\detokenize{proofs/writing-proofs/index:writing-proofs}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic proof writing}}}} chapter.
The basic assertion command is:
\index{Theorem (command)@\spxentry{Theorem}\spxextra{command}}\index{Lemma (command)@\spxentry{Lemma}\spxextra{command}}\index{Fact (command)@\spxentry{Fact}\spxextra{command}}\index{Remark (command)@\spxentry{Remark}\spxextra{command}}\index{Corollary (command)@\spxentry{Corollary}\spxextra{command}}\index{Proposition (command)@\spxentry{Proposition}\spxextra{command}}\index{Property (command)@\spxentry{Property}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Theorem}}\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Lemma}}\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Fact}}\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Remark}}\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Corollary}}\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Proposition}}\phantomsection\label{\detokenize{language/core/definitions:coq:cmd.Property}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-thm_token}]{\sphinxcrossref{\DUrole{hole}{thm\_token}}}}~{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/definitions:grammar-token-thm_token}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-thm_token}]{\sphinxcrossref{\DUrole{hole}{thm\_token}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Theorem}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Lemma}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Fact}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Remark}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Corollary}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Proposition}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Property}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
After the statement is asserted, Coq needs a proof. Once a proof of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} under the assumptions represented by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}}s is given and
validated, the proof is generalized into a proof of \sphinxcode{\sphinxupquote{\DUrole{notation}{forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}, {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} and
the theorem is bound to the name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in the global environment.

\sphinxAtStartPar
These commands accept the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute.  See {\hyperref[\detokenize{addendum/program:program-lemma}]{\sphinxcrossref{\DUrole{std,std-ref}{Program Lemma}}}}.

\sphinxAtStartPar
Forms using the \sphinxcode{\sphinxupquote{\DUrole{notation}{with}}} clause are useful for theorems that are proved by simultaneous induction
over a mutually inductive assumption, or that assert mutually dependent
statements in some mutual co\sphinxhyphen{}inductive type. It is equivalent to
{\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} or {\hyperref[\detokenize{language/core/coinductive:coq:cmd.CoFixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}} but using tactics to build the proof of
the statements (or the {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} of the specification, depending on the point of
view). The inductive or co\sphinxhyphen{}inductive types on which the induction or
coinduction has to be done is assumed to be non ambiguous and is guessed by
the system.

\sphinxAtStartPar
Like in a {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} or {\hyperref[\detokenize{language/core/coinductive: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/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}) or
be \sphinxstyleemphasis{guarded by a constructor} (for a {\hyperref[\detokenize{language/core/coinductive: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 global 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{proofs/writing-proofs/proof-mode:coq:cmd.Guarded}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Guarded}}}}}.

\sphinxAtStartPar
This command accepts the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(universes)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(universes)}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(guard)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(guard)}}}}}, and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:attr.using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{using}}}}} attributes.
\index{The term ‘term’ has type ‘type’ which should be Set, Prop or Type (error)@\spxentry{The term ‘term’ has type ‘type’ which should be Set, Prop or Type}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/definitions:coq:exn.The-term-_u2018term_u2019-has-type-_u2018type_u2019-which-should-be-Set,-Prop-or-Type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~term~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~has~type~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~which~should~be~Set,~Prop~or~Type.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘ident’ already exists. (Theorem) (error)@\spxentry{‘ident’ already exists. (Theorem)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/definitions:coq:exn._u2018ident_u2019-already-exists.-(Theorem)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
\sphinxAtStartPar
The name you provided is already defined. You have then to choose
another name.

\end{fulllineitems}\end{savenotes}

\index{Nested proofs are discouraged and not allowed by default. This error probably means that you forgot to close the last ""Proof."" with ""Qed."" or ""Defined."". If you really intended to use nested proofs, you can do so by turning the ""Nested Proofs Allowed"" flag on (error)@\spxentry{Nested proofs are discouraged and not allowed by default. This error probably means that you forgot to close the last ""Proof."" with ""Qed."" or ""Defined."". If you really intended to use nested proofs, you can do so by turning the ""Nested Proofs Allowed"" flag on}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/definitions:coq:exn.Nested-proofs-are-discouraged-and-not-allowed-by-default.-This-error-probably-means-that-you-forgot-to-close-the-last-"Proof."-with-"Qed."-or-"Defined.".-If-you-really-intended-to-use-nested-proofs,-you-can-do-so-by-turning-the-"Nested-Proofs-Allowed"-flag-on}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nested~proofs~are~discouraged~and~not~allowed~by~default.~This~error~probably~means~that~you~forgot~to~close~the~last~"Proof."~with~"Qed."~or~"Defined.".~If~you~really~intended~to~use~nested~proofs,~you~can~do~so~by~turning~the~"Nested~Proofs~Allowed"~flag~on.}}}}
\sphinxAtStartPar
You are asserting a new statement when you're already in proof mode.
This feature, called nested proofs, is disabled by default.
To activate it, turn the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:flag.Nested-Proofs-Allowed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Nested Proofs Allowed}}}}} flag on.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Proofs start with the keyword {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}}. Then Coq enters the proof mode
until the proof is completed. In proof mode, the user primarily enters
tactics (see {\hyperref[\detokenize{proofs/writing-proofs/index:writing-proofs}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic proof writing}}}}). The user may also enter
commands to manage the proof mode (see {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof mode}}}}).

\sphinxAtStartPar
When the proof is complete, use the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} command so the kernel verifies
the proof and adds it to the global environment.

\begin{sphinxadmonition}{note}{Note:}\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
Several statements can be simultaneously asserted provided the
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:flag.Nested-Proofs-Allowed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Nested Proofs Allowed}}}}} flag was turned on.

\item {} 
\sphinxAtStartPar
Not only other assertions but any 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 {} 
\sphinxAtStartPar
Proofs ended by {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} are declared {\hyperref[\detokenize{language/core/conversion:term-opaque}]{\sphinxtermref{\DUrole{xref,std,std-term}{opaque}}}}. Their content cannot be
unfolded (see {\hyperref[\detokenize{proofs/writing-proofs/equality:applyingconversionrules}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying conversion rules}}}}), thus
realizing some form of \sphinxstyleemphasis{proof\sphinxhyphen{}irrelevance}.
Proofs that end with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}} can be unfolded.

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

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

\end{enumerate}
\end{sphinxadmonition}


\subsection{Conversion rules}
\label{\detokenize{language/core/conversion:conversion-rules}}\label{\detokenize{language/core/conversion:id1}}\label{\detokenize{language/core/conversion::doc}}
\sphinxAtStartPar
Coq has conversion rules that can be used to determine if two
terms are equal by definition in CIC, or {\hyperref[\detokenize{language/core/conversion:term-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{convertible}}}}.
Conversion rules consist of reduction rules and expansion rules.
Equality is determined by
converting both terms to a normal form, then verifying they are syntactically
equal (ignoring differences in the names of bound variables by
{\hyperref[\detokenize{language/core/conversion:term-alpha-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{alpha\sphinxhyphen{}conversion}}}}).


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:applyingconversionrules}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying conversion rules}}}}, which describes tactics that apply these conversion rules.



\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-reduction}}Reductions} convert terms to something that is incrementally
closer to its normal form.  For example, {\hyperref[\detokenize{language/core/conversion:term-zeta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{zeta\sphinxhyphen{}reduction}}}} removes
\sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} constructs from a term by replacing
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}} wherever \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} appears in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}}.
The resulting term may be longer or shorter than the original.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Eval} \PYG{k}{cbv} \PYG{n}{zeta} \PYG{k}{in} \PYG{k}{let} \PYG{n}{i} \PYG{o}{:=} \PYG{l+m+mi}{1} \PYG{k}{in} \PYG{n}{i} \PYG{o}{+} \PYG{n}{i}\PYG{o}{.}
    \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{n}{nat}
\end{sphinxVerbatim}

\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-expansion}}Expansions} are reductions applied in the opposite direction,
for example expanding \sphinxcode{\sphinxupquote{2 + 2}} to \sphinxcode{\sphinxupquote{let i := 2 in i + i}}.  While applying
reductions gives a unique result, the associated
expansion may not be unique.  For example, \sphinxcode{\sphinxupquote{2 + 2}} could also be
expanded to \sphinxcode{\sphinxupquote{let i := 2 in i + 2}}.  Reductions that have a unique inverse
expansion are also referred to as \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-contraction}}contractions}.

\sphinxAtStartPar
The normal form is defined as the result of applying a particular
set of conversion rules (beta\sphinxhyphen{}, delta\sphinxhyphen{}, iota\sphinxhyphen{} and zeta\sphinxhyphen{}reduction and eta\sphinxhyphen{}expansion)
repeatedly until it's no longer possible to apply any of them.

\sphinxAtStartPar
Sometimes the result of a reduction tactic will be a simple value, for example reducing
\sphinxcode{\sphinxupquote{2*3+4}} with \sphinxcode{\sphinxupquote{cbv beta delta iota}} to \sphinxcode{\sphinxupquote{10}}, which requires applying several
reduction rules repeatedly.  In other cases, it may yield an expression containing
variables, axioms or opaque contants that can't be reduced.

\sphinxAtStartPar
The useful conversion rules are shown below.  All of them except for eta\sphinxhyphen{}expansion
can be applied with conversion tactics such as {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}}:
\begin{quote}


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
Conversion name
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Description
\\
\hline
\sphinxAtStartPar
beta\sphinxhyphen{}reduction
&
\sphinxAtStartPar
eliminates \sphinxcode{\sphinxupquote{fun}}
\\
\hline
\sphinxAtStartPar
delta\sphinxhyphen{}reduction
&
\sphinxAtStartPar
replaces a defined variable or constant with its definition
\\
\hline
\sphinxAtStartPar
zeta\sphinxhyphen{}reduction
&
\sphinxAtStartPar
eliminates \sphinxcode{\sphinxupquote{let}}
\\
\hline
\sphinxAtStartPar
eta\sphinxhyphen{}expansion
&
\sphinxAtStartPar
replaces a term \sphinxcode{\sphinxupquote{f}} of type \sphinxcode{\sphinxupquote{forall a : A, B}} with \sphinxcode{\sphinxupquote{fun x : A => f x}}
\\
\hline
\sphinxAtStartPar
match\sphinxhyphen{}reduction
&
\sphinxAtStartPar
eliminates \sphinxcode{\sphinxupquote{match}}
\\
\hline
\sphinxAtStartPar
fix\sphinxhyphen{}reduction
&
\sphinxAtStartPar
replaces a \sphinxcode{\sphinxupquote{fix}} with a {\hyperref[\detokenize{language/core/conversion:term-beta-redex}]{\sphinxtermref{\DUrole{xref,std,std-term}{beta\sphinxhyphen{}redex}}}};
recursive calls to the symbol are replaced with the \sphinxcode{\sphinxupquote{fix}} term
\\
\hline
\sphinxAtStartPar
cofix\sphinxhyphen{}reduction
&
\sphinxAtStartPar
replaces a \sphinxcode{\sphinxupquote{cofix}} with a {\hyperref[\detokenize{language/core/conversion:term-beta-redex}]{\sphinxtermref{\DUrole{xref,std,std-term}{beta\sphinxhyphen{}redex}}}};
recursive calls to the symbol are replaced with the \sphinxcode{\sphinxupquote{cofix}} term
\\
\hline
\sphinxAtStartPar
iota\sphinxhyphen{}reduction
&
\sphinxAtStartPar
match\sphinxhyphen{}, fix\sphinxhyphen{} and cofix\sphinxhyphen{}reduction together
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\end{quote}

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:applyingconversionrules}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying conversion rules}}}}
describes tactics that only apply conversion rules.
(Other tactics may use conversion rules in addition
to other changes to the proof state.)


\subsubsection{α\sphinxhyphen{}conversion}
\label{\detokenize{language/core/conversion:conversion}}
\sphinxAtStartPar
Two terms are \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-alpha-convertible}}α\sphinxhyphen{}convertible} if they are syntactically
equal ignoring differences in the names of variables bound within the expression.
For example \sphinxcode{\sphinxupquote{forall x, x + 0 = x}} is α\sphinxhyphen{}convertible with \sphinxcode{\sphinxupquote{forall y, y + 0 = y}}.


\subsubsection{β\sphinxhyphen{}reduction}
\label{\detokenize{language/core/conversion:reduction}}
\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-beta-reduction}}β\sphinxhyphen{}reduction} reduces a \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-beta-redex}}beta\sphinxhyphen{}redex}, which is
a term in the form \sphinxcode{\sphinxupquote{(fun x => t) u}}.  (Beta\sphinxhyphen{}redex
is short for "beta\sphinxhyphen{}reducible expression", a term from lambda calculus.
See \sphinxhref{https://en.wikipedia.org/wiki/Beta\_normal\_form\#Beta\_reduction}{Beta reduction}%
\begin{footnote}[11]\sphinxAtStartFootnote
\sphinxnolinkurl{https://en.wikipedia.org/wiki/Beta\_normal\_form\#Beta\_reduction}
%
\end{footnote}
for more background.)

\sphinxAtStartPar
Formally, in any {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-global-environment}]{\sphinxtermref{\DUrole{xref,std,std-term}{global environment}}}} \(E\) and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-local-context}]{\sphinxtermref{\DUrole{xref,std,std-term}{local context}}}}
\(Γ\), the beta\sphinxhyphen{}reduction rule is:
\begin{description}
\phantomsection\label{\detokenize{language/core/conversion:inference-Beta}}\item[{Beta}] \leavevmode \begin{equation*}
\begin{split}\frac{%
%
}{%
E[Γ] ⊢ ((λx:T.~t)~u)~\triangleright_β~\subst{t}{x}{u}%
}\end{split}
\end{equation*}\end{description}

\sphinxAtStartPar
We say that \(\subst{t}{x}{u}\) is the \sphinxstyleemphasis{β\sphinxhyphen{}contraction} of
\(((λx:T.~t)~u)\) and, conversely, that \(((λ x:T.~t)~u)\) is the
\sphinxstyleemphasis{β\sphinxhyphen{}expansion} of \(\subst{t}{x}{u}\).

\sphinxAtStartPar
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 {[}\hyperlink{cite.zebibliography:id10}{Coq85}{]}.


\subsubsection{δ\sphinxhyphen{}reduction}
\label{\detokenize{language/core/conversion:delta-reduction-sect}}\label{\detokenize{language/core/conversion:id3}}
\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-delta-reduction}}δ\sphinxhyphen{}reduction} replaces variables defined in
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-local-context}]{\sphinxtermref{\DUrole{xref,std,std-term}{local contexts}}}}
or {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} defined in the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-global-environment}]{\sphinxtermref{\DUrole{xref,std,std-term}{global environment}}}} with their values.
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-unfold}}Unfolding} means to replace a constant by its definition. Formally, this is:
\begin{description}
\phantomsection\label{\detokenize{language/core/conversion:inference-Delta-Local}}\item[{Delta\sphinxhyphen{}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/core/conversion:inference-Delta-Global}}\item[{Delta\sphinxhyphen{}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}

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/conversion:term-delta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{Delta\sphinxhyphen{}reduction}}}} only unfolds {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} that are
marked \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-transparent}}transparent}.  \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-opaque}}Opaque} is the opposite of
transparent; {\hyperref[\detokenize{language/core/conversion:term-delta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{delta\sphinxhyphen{}reduction}}}} doesn't unfold opaque constants.


\subsubsection{ι\sphinxhyphen{}reduction}
\label{\detokenize{language/core/conversion:id4}}
\sphinxAtStartPar
A specific conversion rule is associated with the inductive objects in
the global environment. We shall give later on (see Section
{\hyperref[\detokenize{language/core/inductive:well-formed-inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Well\sphinxhyphen{}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
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-iota-reduction}}ι\sphinxhyphen{}reduction}
and is more precisely studied in {[}\hyperlink{cite.zebibliography:id37}{PM93a}, \hyperlink{cite.zebibliography:id51}{Wer94}{]}.


\subsubsection{ζ\sphinxhyphen{}reduction}
\label{\detokenize{language/core/conversion:id6}}
\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-zeta-reduction}}ζ\sphinxhyphen{}reduction} removes {\hyperref[\detokenize{language/core/definitions:let-in}]{\sphinxcrossref{\DUrole{std,std-ref}{let\sphinxhyphen{}in definitions}}}}
in terms by
replacing the defined variable by its value. One way this reduction differs from
δ\sphinxhyphen{}reduction is that the declaration is removed from the term entirely.
Formally, this is:
\begin{description}
\phantomsection\label{\detokenize{language/core/conversion: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:U}{t}~\triangleright_ζ~\subst{t}{x}{u}%
}\end{split}
\end{equation*}\end{description}


\subsubsection{η\sphinxhyphen{}expansion}
\label{\detokenize{language/core/conversion:expansion}}\label{\detokenize{language/core/conversion:eta-expansion-sect}}
\sphinxAtStartPar
Another important concept is \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-eta-expansion}}η\sphinxhyphen{}expansion}. It is legal to identify any
term \(t\) of functional type \(∀ x:T,~U\) with its so\sphinxhyphen{}called η\sphinxhyphen{}expansion
\begin{equation*}
\begin{split}λx:T.~(t~x)\end{split}
\end{equation*}
\sphinxAtStartPar
for \(x\) an arbitrary variable name fresh in \(t\).

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
We deliberately do not define η\sphinxhyphen{}reduction:
\begin{equation*}
\begin{split}λ x:T.~(t~x)~\not\triangleright_η~t\end{split}
\end{equation*}
\sphinxAtStartPar
This is because, in general, the type of \(t\) need not 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*}
\sphinxAtStartPar
then
\begin{equation*}
\begin{split}λ x:\Type(1).~(f~x) ~:~ ∀ x:\Type(1),~\Type(1)\end{split}
\end{equation*}
\sphinxAtStartPar
We could not allow
\begin{equation*}
\begin{split}λ x:\Type(1).~(f~x) ~\triangleright_η~ f\end{split}
\end{equation*}
\sphinxAtStartPar
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{Examples}
\label{\detokenize{language/core/conversion:examples}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Simple delta, fix, beta and match reductions}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{+}} is a {\hyperref[\detokenize{user-extensions/syntax-extensions:notations}]{\sphinxcrossref{\DUrole{std,std-ref}{notation}}}} for \sphinxcode{\sphinxupquote{Nat.add}}, which is defined
with a {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{o}{=} 
    \PYG{k}{fix} \PYG{n}{add} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
      \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
      \PYG{o}{|} \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}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    
    \PYG{k+kn}{Arguments} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}

\PYG{k+kn}{Goal} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{1} \PYG{o}{=} \PYG{l+m+mi}{2}

\PYG{k}{cbv} \PYG{n}{delta}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{fix} \PYG{n}{add} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
         \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
         \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
         \PYG{o}{|} \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{l+m+mi}{1} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{2}

\PYG{k}{cbv} \PYG{k}{fix}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}}
       \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
       \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
       \PYG{o}{|} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}}
           \PYG{n}{S}
             \PYG{o}{(}\PYG{o}{(}\PYG{k}{fix} \PYG{n}{add} \PYG{o}{(}\PYG{n}{n0} \PYG{n}{m0} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n0}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
                 \PYG{k}{match} \PYG{n}{n0} \PYG{k}{with}
                 \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m0}
                 \PYG{o}{|} \PYG{n}{S} \PYG{n}{p0} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{add} \PYG{n}{p0} \PYG{n}{m0}\PYG{o}{)}
                 \PYG{k}{end}\PYG{o}{)} \PYG{n}{p} \PYG{n}{m}\PYG{o}{)}
       \PYG{k}{end}\PYG{o}{)} \PYG{l+m+mi}{1} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{2}

\PYG{k}{cbv} \PYG{n}{beta}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{match} \PYG{l+m+mi}{1} \PYG{k}{with}
      \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{1}
      \PYG{o}{|} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}}
          \PYG{n}{S}
            \PYG{o}{(}\PYG{o}{(}\PYG{k}{fix} \PYG{n}{add} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
                \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
                \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
                \PYG{o}{|} \PYG{n}{S} \PYG{n}{p0} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{add} \PYG{n}{p0} \PYG{n}{m}\PYG{o}{)}
                \PYG{k}{end}\PYG{o}{)} \PYG{n}{p} \PYG{l+m+mi}{1}\PYG{o}{)}
      \PYG{k}{end} \PYG{o}{=} \PYG{l+m+mi}{2}

\PYG{k}{cbv} \PYG{k}{match}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{o}{(}\PYG{k}{fix} \PYG{n}{add} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
            \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
            \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
            \PYG{o}{|} \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{l+m+mi}{0} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}

\sphinxAtStartPar
The term can be fully reduced with \sphinxcode{\sphinxupquote{cbv}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{1} \PYG{o}{=} \PYG{l+m+mi}{2}

\PYG{k}{cbv}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}


\subsubsection{Proof Irrelevance}
\label{\detokenize{language/core/conversion:proof-irrelevance}}\label{\detokenize{language/core/conversion:id7}}
\sphinxAtStartPar
It is legal to identify any two terms whose common type is a strict
proposition \(A : \SProp\). Terms in a strict propositions are
therefore called \sphinxstyleemphasis{irrelevant}.


\subsubsection{Convertibility}
\label{\detokenize{language/core/conversion:convertibility}}\label{\detokenize{language/core/conversion:id8}}
\sphinxAtStartPar
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 β, δ, ι or ζ.

\sphinxAtStartPar
We say that two terms \(t_1\) and \(t_2\) are
\sphinxstyleemphasis{βδιζη\sphinxhyphen{}convertible}, or simply \DUrole{term-defn}{\phantomsection\label{\detokenize{language/core/conversion:term-convertible}}convertible}, or
{\hyperref[\detokenize{proofs/writing-proofs/equality:term-definitional-equality}]{\sphinxtermref{\DUrole{xref,std,std-term}{definitionally equal}}}}, 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 up to irrelevant subterms, or they are convertible up to η\sphinxhyphen{}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\).

\sphinxAtStartPar
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*}
\sphinxAtStartPar
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*}
\sphinxAtStartPar
and
\begin{equation*}
\begin{split}E[Γ] ⊢ t~w_1' … w_m' ≤_{βδιζη} t~w_1 … w_m.\end{split}
\end{equation*}
\sphinxAtStartPar
Furthermore, we consider
\begin{equation*}
\begin{split}E[Γ] ⊢ c~v_1 … v_m =_{βδιζη} c'~v_1' … v_m'\end{split}
\end{equation*}
\sphinxAtStartPar
convertible if
\begin{equation*}
\begin{split}E[Γ] ⊢ v_i =_{βδιζη} v_i'\end{split}
\end{equation*}
\sphinxAtStartPar
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*}
\sphinxAtStartPar
and
\begin{equation*}
\begin{split}E[Γ] ⊢ c'~v_1' … v_m' : t'~ w_1' … w_m '\end{split}
\end{equation*}
\sphinxAtStartPar
and we have
\begin{equation*}
\begin{split}E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m'.\end{split}
\end{equation*}
\sphinxAtStartPar
The convertibility relation allows introducing a new typing rule which
says that two convertible well\sphinxhyphen{}formed types have the same inhabitants.


\subsection{Typing rules}
\label{\detokenize{language/cic:typing-rules}}\label{\detokenize{language/cic::doc}}
\sphinxAtStartPar
The underlying formal language of Coq is a
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/cic:term-Calculus-of-Inductive-Constructions}}Calculus of Inductive Constructions} (CIC) whose inference rules
are presented in this
chapter. The history of this formalism as well as pointers to related
work are provided in a separate chapter; see {\hyperref[\detokenize{history:history}]{\sphinxcrossref{\DUrole{std,std-ref}{Early history of Coq}}}}.


\subsubsection{The terms}
\label{\detokenize{language/cic:the-terms}}\label{\detokenize{language/cic:id1}}
\sphinxAtStartPar
The expressions of the 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\) \sphinxstyleemphasis{of type} \(T\)” is written “\(x:T\)”. Informally, “\(x:T\)” can be thought as
“\(x\) \sphinxstyleemphasis{belongs to} \(T\)”.

\sphinxAtStartPar
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}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
the sorts \(\SProp\), \(\Prop\), \(\Set\), \(\Type(i)\) are terms.

\item {} 
\sphinxAtStartPar
variables, hereafter ranged over by letters \(x\), \(y\), etc., are terms

\item {} 
\sphinxAtStartPar
constants, hereafter ranged over by letters \(c\), \(d\), etc., are terms.

\item {} 
\sphinxAtStartPar
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 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 {} 
\sphinxAtStartPar
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}{=>} \DUrole{name}{u}}}
in Coq concrete syntax) is a term. This is a notation for the
λ\sphinxhyphen{}abstraction of λ\sphinxhyphen{}calculus {[}\hyperlink{cite.zebibliography:id3}{Bar81}{]}. The term \(λ x:T .~u\) is a function
which maps elements of \(T\) to the expression \(u\).

\item {} 
\sphinxAtStartPar
if \(t\) and \(u\) are terms then \((t~u)\) is a term
(\sphinxcode{\sphinxupquote{\DUrole{name}{t} \DUrole{name}{u}}} in Coq concrete
syntax). The term \((t~u)\) reads as “\(t\) applied to \(u\)”.

\item {} 
\sphinxAtStartPar
if \(x\) is a variable, and \(t\), \(T\) and \(u\) are
terms then \(\letin{x}{t:T}{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\sphinxhyphen{}in” construction of
functional programs such as ML or Scheme.

\end{enumerate}
\phantomsection\label{\detokenize{language/cic:free-variables}}
\sphinxAtStartPar
\sphinxstylestrong{Free variables.}
The notion of free variables is defined as usual. In the expressions
\(λx:T.~U\) and \(∀ x:T,~U\) the occurrences of \(x\) in \(U\) are bound.

\phantomsection\label{\detokenize{language/cic:substitution}}
\sphinxAtStartPar
\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}}
\sphinxAtStartPar
\sphinxstylestrong{The logical vs programming readings.}
The constructions of the CIC can be used to express both logical and
programming notions, accordingly to the Curry\sphinxhyphen{}Howard correspondence
between proofs and programs, and between propositions and types
{[}\hyperlink{cite.zebibliography:id15}{CFC58}, \hyperlink{cite.zebibliography:id5}{dB72}, \hyperlink{cite.zebibliography:id27}{How80}{]}.

\sphinxAtStartPar
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→True which is an
implicative proposition, to denote \(\nat →\Prop\) which is the type of
unary predicates over the natural numbers, etc.

\sphinxAtStartPar
Let us assume that \sphinxcode{\sphinxupquote{mult}} is a function of type \(\nat→\nat→\nat\) and \sphinxcode{\sphinxupquote{eqnat}} a
predicate of type \(\nat→\nat→ \Prop\). The λ\sphinxhyphen{}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{name}{nat} \DUrole{operator}{=>} \DUrole{name}{mult} \DUrole{name}{x} \DUrole{name}{x}}}
in 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{name}{nat} \DUrole{operator}{=>} \DUrole{name}{eqnat} \DUrole{name}{x} \DUrole{literal,number,integer}{0}}}
in 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.

\sphinxAtStartPar
Furthermore \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{nat}\DUrole{operator}{,} \DUrole{name}{P} \DUrole{name}{x}}} will represent the type of functions
which associate with each natural number \(n\) an object of type \((P~n)\) and
consequently represent the type of proofs of the formula “\(∀ x.~P(x)\)”.


\subsubsection{Typing rules}
\label{\detokenize{language/cic:id4}}\label{\detokenize{language/cic:id5}}
\sphinxAtStartPar
As objects of type theory, terms are subjected to \sphinxstyleemphasis{type discipline}.
The well typing of a term depends on a local context and a global environment.

\phantomsection\label{\detokenize{language/cic:local-context}}
\sphinxAtStartPar
\sphinxstylestrong{Local context.}
A {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-local-context}]{\sphinxtermref{\DUrole{xref,std,std-term}{local context}}}} is an ordered list of declarations of \sphinxstyleemphasis{variables}.
The declaration of a variable \(x\) is
either an \sphinxstyleemphasis{assumption}, written \(x:T\) (where \(T\) is a type) or a
\sphinxstyleemphasis{definition}, written \(x:=t:T\). Local contexts are written in brackets,
for example \([x:T;~y:=u:U;~z:V]\). The variables
declared in a local context must be distinct. If \(Γ\) is a local context
that declares \(x\), we
write \(x ∈ Γ\). Writing \((x:T) ∈ Γ\) means there is an assumption
or a definition giving the type \(T\) to \(x\) in \(Γ\).
If \(Γ\) defines \(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. Writing \(Γ_1 ; Γ_2\) means
concatenation of the local context \(Γ_1\) and the local context \(Γ_2\).

\phantomsection\label{\detokenize{language/cic:global-environment}}
\sphinxAtStartPar
\sphinxstylestrong{Global environment.}
A {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-global-environment}]{\sphinxtermref{\DUrole{xref,std,std-term}{global environment}}}} is an ordered list of \sphinxstyleemphasis{declarations}.
Global declarations are either \sphinxstyleemphasis{assumptions}, \sphinxstyleemphasis{definitions}
or declarations of inductive objects. Inductive
objects declare both constructors and inductive or
coinductive types (see Section {\hyperref[\detokenize{language/core/inductive:inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Theory of inductive definitions}}}}).

\sphinxAtStartPar
In the global environment,
\sphinxstyleemphasis{assumptions} are written as
\((c:T)\), indicating that \(c\) is of the type \(T\). \sphinxstyleemphasis{Definitions}
are written as \(c:=t:T\), indicating that \(c\) has the value \(t\)
and type \(T\). We shall call
such names {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}}. For the rest of the chapter, the \(E;~c:T\) denotes
the global environment \(E\) enriched with the assumption \(c:T\).
Similarly, \(E;~c:=t:T\) denotes the global environment \(E\) enriched with the
definition \((c:=t:T)\).

\sphinxAtStartPar
The rules for inductive definitions (see Section
{\hyperref[\detokenize{language/core/inductive:inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Theory of inductive definitions}}}}) have to be considered as assumption
rules in 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}}
\sphinxAtStartPar
\sphinxstylestrong{Typing rules.}
In the following, we define simultaneously two judgments. The first
one \(\WTEG{t}{T}\) means the term \(t\) is well\sphinxhyphen{}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\sphinxhyphen{}formed and the local
context \(Γ\) is a valid local context in this global environment.

\sphinxAtStartPar
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\sphinxhyphen{}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\sphinxhyphen{}Local\sphinxhyphen{}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\sphinxhyphen{}Local\sphinxhyphen{}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\sphinxhyphen{}Global\sphinxhyphen{}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\sphinxhyphen{}Global\sphinxhyphen{}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-SProp}}\item[{Ax\sphinxhyphen{}SProp}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
}{%
\WTEG{\SProp}{\Type(1)}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-Ax-Prop}}\item[{Ax\sphinxhyphen{}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\sphinxhyphen{}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\sphinxhyphen{}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-SProp}}\item[{Prod\sphinxhyphen{}SProp}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{T}{s}%
\hspace{3em}%
s \in {\Sort}%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{U}{\SProp}%
}{%
\WTEG{\forall~x:T,U}{\SProp}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-Prod-Prop}}\item[{Prod\sphinxhyphen{}Prop}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{T}{s}%
\hspace{3em}%
s \in \Sort%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{U}{\Prop}%
}{%
\WTEG{∀ x:T,~U}{\Prop}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-Prod-Set}}\item[{Prod\sphinxhyphen{}Set}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{T}{s}%
\hspace{3em}%
s \in \{\SProp, \Prop, \Set\}%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{U}{\Set}%
}{%
\WTEG{∀ x:T,~U}{\Set}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-Prod-Type}}\item[{Prod\sphinxhyphen{}Type}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{T}{s}%
\hspace{3em}%
s \in \{\SProp, \Type(i)\}%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{U}{\Type(i)}%
}{%
\WTEG{∀ 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{∀ x:T,~U}{s}%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{t}{U}%
}{%
\WTEG{λ x:T\mto t}{∀ 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}{∀ 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:}
\sphinxAtStartPar
\sphinxstylestrong{Prod\sphinxhyphen{}Prop} and \sphinxstylestrong{Prod\sphinxhyphen{}Set} typing\sphinxhyphen{}rules make sense if we consider the
semantic difference between \(\Prop\) and \(\Set\):
\begin{itemize}
\item {} 
\sphinxAtStartPar
All values of a type that has a sort \(\Set\) are extractable.

\item {} 
\sphinxAtStartPar
No values of a type that has a sort \(\Prop\) are extractable.

\end{itemize}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
We may have \(\letin{x}{t:T}{u}\) well\sphinxhyphen{}typed without having
\(((λ x:T.~u)~t)\) well\sphinxhyphen{}typed (where \(T\) is a type of
\(t\)). This is because the value \(t\) associated with
\(x\) may be used in a conversion rule
(see Section {\hyperref[\detokenize{language/core/conversion:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}}).
\end{sphinxadmonition}


\subsubsection{Subtyping rules}
\label{\detokenize{language/cic:subtyping-rules}}\label{\detokenize{language/cic:id6}}
\sphinxAtStartPar
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 CIC).
This property extends the equivalence relation of convertibility into
a \sphinxstyleemphasis{subtyping} relation inductively defined by:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
if \(E[Γ] ⊢ t =_{βδιζη} u\) then \(E[Γ] ⊢ t ≤_{βδιζη} u\),

\item {} 
\sphinxAtStartPar
if \(i ≤ j\) then \(E[Γ] ⊢ \Type(i) ≤_{βδιζη} \Type(j)\),

\item {} 
\sphinxAtStartPar
for any \(i\), \(E[Γ] ⊢ \Set ≤_{βδιζη} \Type(i)\),

\item {} 
\sphinxAtStartPar
\(E[Γ] ⊢ \Prop ≤_{βδιζη} \Set\), hence, by transitivity,
\(E[Γ] ⊢ \Prop ≤_{βδιζη} \Type(i)\), for any \(i\)
(note: \(\SProp\) is not related by cumulativity to any other term)

\item {} 
\sphinxAtStartPar
if \(E[Γ] ⊢ T =_{βδιζη} U\) and
\(E[Γ::(x:T)] ⊢ T' ≤_{βδιζη} U'\) then
\(E[Γ] ⊢ ∀x:T,~T′ ≤_{βδιζη} ∀ x:U,~U′\).

\item {} 
\sphinxAtStartPar
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)}, S)∈Γ_I\)
and
\((t' : ∀Γ_P' ,∀Γ_{\mathit{Arr}(t)}', S')∈Γ_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_{k,1} … v_{k,m} ]\end{split}
\end{equation*}
\sphinxAtStartPar
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_{k,1}' … v_{k,m}' ]\end{split}
\end{equation*}
\sphinxAtStartPar
respectively then
\begin{equation*}
\begin{split}E[Γ] ⊢ t~w_1 … w_m ≤_{βδιζη} t'~w_1' … w_m'\end{split}
\end{equation*}
\sphinxAtStartPar
(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*}
\sphinxAtStartPar
for \(1 ≤ i ≤ m\) and we have
\begin{equation*}
\begin{split}E[Γ] ⊢ T_{i,j} ≤_{βδιζη} T_{i,j}'\end{split}
\end{equation*}
\sphinxAtStartPar
and
\begin{equation*}
\begin{split}E[Γ] ⊢ A_i ≤_{βδιζη} A_i'\end{split}
\end{equation*}
\sphinxAtStartPar
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}

\sphinxAtStartPar
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}}
\sphinxAtStartPar
\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 β\sphinxhyphen{}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*}
\sphinxAtStartPar
Iterating the process of head reduction until the head of the reduced
term is no more an abstraction leads to the \sphinxstyleemphasis{β\sphinxhyphen{}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*}
\sphinxAtStartPar
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\sphinxhyphen{}normal forms involving δ, ι
and ζ reductions or any combination of those can also be defined.


\subsubsection{Admissible rules for global environments}
\label{\detokenize{language/cic:admissible-rules-for-global-environments}}\label{\detokenize{language/cic:id7}}
\sphinxAtStartPar
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}}
\sphinxAtStartPar
\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\).

\sphinxAtStartPar
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}}
\sphinxAtStartPar
\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)}}{\subst{Γ}{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*}
\sphinxAtStartPar
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}}
\sphinxAtStartPar
\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}}
\sphinxAtStartPar
\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}


\subsubsection{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}}
\sphinxAtStartPar
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{\sphinxhyphen{}impredicative\sphinxhyphen{}set}}. For example, using the ordinary \sphinxcode{\sphinxupquote{coqtop}}
command, the following is rejected,

\begin{sphinxadmonition}{note}{Example}

\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{n}{Cannot} \PYG{n}{enforce} \PYG{k+kn}{Set}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
while it will type check, if one uses instead the \sphinxcode{\sphinxupquote{coqtop}}
\sphinxcode{\sphinxupquote{\sphinxhyphen{}impredicative\sphinxhyphen{}set}} option..

\sphinxAtStartPar
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}

\sphinxAtStartPar
This extension has consequences on the inductive definitions which are
allowed. In the impredicative system, one can build so\sphinxhyphen{}called \sphinxstyleemphasis{large
inductive definitions} like the example of second\sphinxhyphen{}order existential
quantifier (\sphinxcode{\sphinxupquote{\DUrole{name}{exSet}}}).

\sphinxAtStartPar
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}


\subsection{Variants and the \sphinxstyleliteralintitle{\sphinxupquote{match}} construct}
\label{\detokenize{language/core/variants:variants-and-the-match-construct}}\label{\detokenize{language/core/variants::doc}}

\subsubsection{Variants}
\label{\detokenize{language/core/variants:variants}}\index{Variant (command)@\spxentry{Variant}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/variants:coq:cmd.Variant}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Variant~{\hyperref[\detokenize{language/core/variants:grammar-token-variant_definition}]{\sphinxcrossref{\DUrole{hole}{variant\_definition}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/variants:grammar-token-variant_definition}]{\sphinxcrossref{\DUrole{hole}{variant\_definition}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/variants:grammar-token-variant_definition}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-variant_definition}]{\sphinxcrossref{\DUrole{hole}{variant\_definition}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{| \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} := \DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/inductive:grammar-token-constructor}]{\sphinxcrossref{\DUrole{hole}{constructor}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}]{\sphinxcrossref{\DUrole{hole}{decl\_notations}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The {\hyperref[\detokenize{language/core/variants:coq:cmd.Variant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variant}}}}} command is similar to the {\hyperref[\detokenize{language/core/inductive: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/core/variants:coq:cmd.Variant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variant}}}}}). No induction scheme is generated for
this variant, unless the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Nonrecursive-Elimination-Schemes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Nonrecursive Elimination Schemes}}}}} flag is on.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}},
{\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template)}}}}}, {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative)}}}}}, and
{\hyperref[\detokenize{language/core/variants:coq:attr.private(matching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{private(matching)}}}}} attributes.
\index{The ‘natural’ th argument of ‘ident’ must be ‘ident’ in ‘type’ (error)@\spxentry{The ‘natural’ th argument of ‘ident’ must be ‘ident’ in ‘type’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/variants:coq:exn.The-_u2018natural_u2019-th-argument-of-_u2018ident_u2019-must-be-_u2018ident_u2019-in-_u2018type_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~th~argument~of~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~must~be~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Private (matching) inductive types}
\label{\detokenize{language/core/variants:private-matching-inductive-types}}\index{private(matching) (attribute)@\spxentry{private(matching)}\spxextra{attribute}}\index{Private (attribute)@\spxentry{Private}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/variants:coq:attr.private(matching)}}\phantomsection\label{\detokenize{language/core/variants:coq:attr.Private}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{private(matching)}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}} can be used to forbid the use of the \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}}
construct on objects of this inductive type outside of the module
where it is defined.  There is also a legacy syntax using the
\sphinxcode{\sphinxupquote{Private}} prefix (cf. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}).

\sphinxAtStartPar
The main use case of private (matching) inductive types is to emulate
quotient types / higher\sphinxhyphen{}order inductive types in projects such as
the \sphinxhref{https://github.com/HoTT/HoTT}{HoTT library}%
\begin{footnote}[12]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/HoTT/HoTT}
%
\end{footnote}.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{Foo}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{Foo} \PYG{n}{started}

\PYG{o}{\PYGZsh{}}\PYG{o}{[} \PYG{n}{private}\PYG{o}{(}\PYG{n}{matching}\PYG{o}{)} \PYG{o}{]} \PYG{k+kn}{Inductive} \PYG{n}{my\PYGZus{}nat} \PYG{o}{:=} \PYG{n}{my\PYGZus{}O} \PYG{o}{:} \PYG{n}{my\PYGZus{}nat} \PYG{o}{|} \PYG{n}{my\PYGZus{}S} \PYG{o}{:} \PYG{n}{my\PYGZus{}nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{my\PYGZus{}nat}\PYG{o}{.}
    \PYG{n}{my\PYGZus{}nat} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{my\PYGZus{}nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{x} \PYG{k}{with} \PYG{n}{my\PYGZus{}O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true} \PYG{o}{|} \PYG{n}{my\PYGZus{}S} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false} \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{my\PYGZus{}nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
                      \PYG{o}{|} \PYG{n}{my\PYGZus{}O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
                      \PYG{o}{|} \PYG{n}{my\PYGZus{}S} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
                      \PYG{k}{end}
         \PYG{o}{:} \PYG{n}{my\PYGZus{}nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}

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

\PYG{k+kn}{Import} \PYG{n}{Foo}\PYG{o}{.}
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{my\PYGZus{}nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{x} \PYG{k}{with} \PYG{n}{my\PYGZus{}O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true} \PYG{o}{|} \PYG{n}{my\PYGZus{}S} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false} \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{k}{case} \PYG{n}{analysis} \PYG{n}{on} \PYG{n}{a} \PYG{n}{private} \PYG{n}{type}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

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

\subsubsection{Definition by cases: match}
\label{\detokenize{language/core/variants:definition-by-cases-match}}\label{\detokenize{language/core/variants:match-term}}\label{\detokenize{language/core/variants:index-0}}
\sphinxAtStartPar
Objects of inductive types can be destructured by a case\sphinxhyphen{}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.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/variants:grammar-token-term_match}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-term_match}]{\sphinxcrossref{\DUrole{hole}{term\_match}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{match \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-case_item}]{\sphinxcrossref{\DUrole{hole}{case\_item}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} \DUrole{repeat-wrapper}{\DUrole{repeat}{return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}\DUrole{notation-sup}{?}} with \DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-eqn}]{\sphinxcrossref{\DUrole{hole}{eqn}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}} end}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/variants:grammar-token-case_item}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-case_item}]{\sphinxcrossref{\DUrole{hole}{case\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{as {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{in {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/variants:grammar-token-eqn}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-eqn}]{\sphinxcrossref{\DUrole{hole}{eqn}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/variants:grammar-token-pattern}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern10}]{\sphinxcrossref{\DUrole{hole}{pattern10}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern10}]{\sphinxcrossref{\DUrole{hole}{pattern10}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/variants:grammar-token-pattern10}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern10}]{\sphinxcrossref{\DUrole{hole}{pattern10}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern1}]{\sphinxcrossref{\DUrole{hole}{pattern1}}}} as {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern1}]{\sphinxcrossref{\DUrole{hole}{pattern1}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern1}]{\sphinxcrossref{\DUrole{hole}{pattern1}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{@ {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern1}]{\sphinxcrossref{\DUrole{hole}{pattern1}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/variants:grammar-token-pattern1}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern1}]{\sphinxcrossref{\DUrole{hole}{pattern1}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern0}]{\sphinxcrossref{\DUrole{hole}{pattern0}}}} \% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern0}]{\sphinxcrossref{\DUrole{hole}{pattern0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/variants:grammar-token-pattern0}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern0}]{\sphinxcrossref{\DUrole{hole}{pattern0}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{| \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} := {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{*}} |\}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-number}]{\sphinxcrossref{\DUrole{hole}{number}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Note that the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} ::= {\hyperref[\detokenize{language/core/variants:grammar-token-pattern10}]{\sphinxcrossref{\DUrole{hole}{pattern10}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} production
is not supported in \sphinxcode{\sphinxupquote{\DUrole{notation}{match}}} patterns.  Trying to use it will give this error:
\index{Casts are not supported in this pattern (error)@\spxentry{Casts are not supported in this pattern}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/variants:coq:exn.Casts-are-not-supported-in-this-pattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Casts~are~not~supported~in~this~pattern.}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
This paragraph describes the basic form of pattern matching. See
Section {\hyperref[\detokenize{language/extensions/match:mult-match}]{\sphinxcrossref{\DUrole{std,std-ref}{Multiple and nested pattern matching}}}} and Chapter {\hyperref[\detokenize{language/extensions/match: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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-case_item}]{\sphinxcrossref{\DUrole{hole}{case\_item}}}}}}} expression, an \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-eqn}]{\sphinxcrossref{\DUrole{hole}{eqn}}}}}}} restricted to a
single \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} restricted to the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}}.

\sphinxAtStartPar
The expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{match {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}\DUrole{notation-sup}{?}} with \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern$_{\text{i}}$}}}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{i}}$}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} end}}} denotes a
\sphinxstyleemphasis{pattern matching} over the term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} (expected to be
of an inductive type \(I\)). The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{i}}$}}}}}}}
are the \sphinxstyleemphasis{branches} of the pattern matching
expression. Each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern$_{\text{i}}$}}}}}}} has the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} must denote a constructor. There should be
exactly one branch for every constructor of \(I\).

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}}} clause gives 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 \sphinxcode{\sphinxupquote{\DUrole{notation}{return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}}} specifies that type.
In this case, \sphinxcode{\sphinxupquote{\DUrole{notation}{return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}}} can usually be omitted as it can be
inferred from the type of the branches \sphinxstepexplicit %
\begin{footnote}[1]\phantomsection\label{\thesphinxscope.1}%
\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}.

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} clause where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
is dependent in the return type. For instance, in the following example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{bool} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n+nb+bp}{true} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{|} \PYG{n+nb+bp}{false} \PYG{o}{:} \PYG{n}{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}{|} \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}{|} \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{n}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{n}{or} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n}{b} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{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{n}{bool} \PYG{n}{x} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n}{x} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{k}{with}
  \PYG{o}{|} \PYG{n+nb+bp}{true} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}introl} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n+nb+bp}{true} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n+nb+bp}{true} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq\PYGZus{}refl} \PYG{n}{bool} \PYG{n+nb+bp}{true}\PYG{o}{)}
  \PYG{o}{|} \PYG{n+nb+bp}{false} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n+nb+bp}{false} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n+nb+bp}{false} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq\PYGZus{}refl} \PYG{n}{bool} \PYG{n+nb+bp}{false}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
the branches have respective types "\sphinxcode{\sphinxupquote{\DUrole{name}{or} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{name}{bool} \DUrole{name,builtin,pseudo}{true} \DUrole{name,builtin,pseudo}{true}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{name}{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{name}{bool} \DUrole{name,builtin,pseudo}{false} \DUrole{name,builtin,pseudo}{true}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{name}{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{name}{bool} \DUrole{name}{b} \DUrole{name,builtin,pseudo}{true}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{name}{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:}
\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{bool\PYGZus{}case} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{n}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{n}{or} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n}{b} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{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{n}{bool} \PYG{n}{b} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n}{b} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{k}{with}
\PYG{o}{|} \PYG{n+nb+bp}{true} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}introl} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n+nb+bp}{true} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n+nb+bp}{true} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq\PYGZus{}refl} \PYG{n}{bool} \PYG{n+nb+bp}{true}\PYG{o}{)}
\PYG{o}{|} \PYG{n+nb+bp}{false} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n+nb+bp}{false} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{n}{bool} \PYG{n+nb+bp}{false} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq\PYGZus{}refl} \PYG{n}{bool} \PYG{n+nb+bp}{false}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
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{language/extensions/match: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 with a clause in the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{in {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\_}\DUrole{notation-sup}{+}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{+}}}}}, where
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is the inductive type of the term being matched;

\item {} 
\sphinxAtStartPar
the holes \sphinxcode{\sphinxupquote{\DUrole{notation}{\_}}} match the parameters of the inductive type: the
return type is not dependent on them.

\item {} 
\sphinxAtStartPar
each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} matches the annotations of the
inductive type: the return type is dependent on them

\item {} 
\sphinxAtStartPar
in the basic case which we describe below, each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}}
is a name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}; see {\hyperref[\detokenize{language/extensions/match:match-in-patterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Patterns in in}}}} for the
general case

\end{itemize}

\sphinxAtStartPar
For instance, in the following example:

\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}{|} \PYG{n}{eq\PYGZus{}refl} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}refl} \PYG{n}{A} \PYG{n}{x}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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/extensions/match:if-then-else}]{\sphinxcrossref{\DUrole{std,std-ref}{Pattern\sphinxhyphen{}matching on boolean values: the if expression}}}} and {\hyperref[\detokenize{language/extensions/match:irrefutable-patterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Irrefutable patterns: the destructuring let variants}}}}).


\subsection{Record types}
\label{\detokenize{language/core/records:record-types}}\label{\detokenize{language/core/records:id1}}\label{\detokenize{language/core/records::doc}}
\sphinxAtStartPar
The {\hyperref[\detokenize{language/core/records: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/core/records: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/core/records:coq:cmd.Record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} construction allows defining
“signatures”.

\phantomsection\label{\detokenize{language/core/records:record-grammar}}\index{Record (command)@\spxentry{Record}\spxextra{command}}\index{Structure (command)@\spxentry{Structure}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records:coq:cmd.Record}}\phantomsection\label{\detokenize{language/core/records:coq:cmd.Structure}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Record}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Structure}}~{\hyperref[\detokenize{language/core/records:grammar-token-record_definition}]{\sphinxcrossref{\DUrole{hole}{record\_definition}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/records:grammar-token-record_definition}]{\sphinxcrossref{\DUrole{hole}{record\_definition}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/records:grammar-token-record_definition}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-record_definition}]{\sphinxcrossref{\DUrole{hole}{record\_definition}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{>}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{:= \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} \{ \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/records:grammar-token-record_field}]{\sphinxcrossref{\DUrole{hole}{record\_field}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}} \DUrole{repeat-wrapper}{\DUrole{repeat}{;}\DUrole{notation-sup}{?}} \}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/records:grammar-token-record_field}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-record_field}]{\sphinxcrossref{\DUrole{hole}{record\_field}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\#{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-attribute}]{\sphinxcrossref{\DUrole{hole}{attribute}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} {]}}\DUrole{notation-sup}{*}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/records:grammar-token-field_body}]{\sphinxcrossref{\DUrole{hole}{field\_body}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{| {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}]{\sphinxcrossref{\DUrole{hole}{decl\_notations}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/records:grammar-token-field_body}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-field_body}]{\sphinxcrossref{\DUrole{hole}{field\_body}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-of_type}]{\sphinxcrossref{\DUrole{hole}{of\_type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-of_type}]{\sphinxcrossref{\DUrole{hole}{of\_type}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/records:grammar-token-term_record}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-term_record}]{\sphinxcrossref{\DUrole{hole}{term\_record}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{| \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/records:grammar-token-field_def}]{\sphinxcrossref{\DUrole{hole}{field\_def}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}} \DUrole{repeat-wrapper}{\DUrole{repeat}{;}\DUrole{notation-sup}{?}} |\}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/records:grammar-token-field_def}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-field_def}]{\sphinxcrossref{\DUrole{hole}{field\_def}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-record_definition}]{\sphinxcrossref{\DUrole{hole}{record\_definition}}}}}}} defines a record named by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}}}}.
The constructor name is given by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
If the constructor name is not specified, then the default name \sphinxcode{\sphinxupquote{\DUrole{notation}{Build\_{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is used,
where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the record name.

\sphinxAtStartPar
If {\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort}}}}} is omitted, the default sort is Type.
Notice that the type of an identifier can depend on a previously\sphinxhyphen{}given identifier. Thus the
order of the fields is important. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}} parameters may be applied to the record as a whole
or to individual fields.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{>}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
If provided, 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).  See {\hyperref[\detokenize{addendum/implicit-coercions:coercions}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit Coercions}}}}.

\end{description}

\sphinxAtStartPar
Notations can be attached to fields using the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}]{\sphinxcrossref{\DUrole{hole}{decl\_notations}}}}}}} annotation.

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/records:coq:cmd.Record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} and {\hyperref[\detokenize{language/core/records:coq:cmd.Structure}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Structure}}}}} are synonyms.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}},
{\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template)}}}}}, {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative)}}}}}, and
{\hyperref[\detokenize{language/core/variants:coq:attr.private(matching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{private(matching)}}}}} attributes.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} : {\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}} := \DUrole{curlies}{\{ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{1}}$}}}} ; {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}} ; {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{3}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{3}}$}}}} \}}}}}.
in which case the correctness of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{3}}$}}}}}}} may rely on the instance \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} may in turn depend on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}}.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The set of rational numbers may be defined as:

\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{n}{bool}
 \PYG{o}{;} \PYG{n}{top} \PYG{o}{:} \PYG{n}{nat}
 \PYG{o}{;} \PYG{n}{bottom} \PYG{o}{:} \PYG{n}{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{n}{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}

\sphinxAtStartPar
Note 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}}.
\end{sphinxadmonition}

\sphinxAtStartPar
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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} : {\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{0}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}}}}.

\sphinxAtStartPar
To build an object of type {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, provide the constructor
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{0}}$}}}}}}} with the appropriate number of terms filling the fields of the record.

\begin{sphinxadmonition}{note}{Example}

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

\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{n}{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{k+kn}{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}

\sphinxAtStartPar
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}}}}).

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{half\PYGZsq{}} \PYG{o}{:=}
  \PYG{o}{\PYGZob{}|} \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}{|\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{half\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

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

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records:coq:flag.Printing-Records}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Records}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is on (this is the default),
use the record syntax (shown above) as the default display format.

\end{fulllineitems}\end{savenotes}


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

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records:coq:table.Printing-Record}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Record~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-table}]{\sphinxtermref{\DUrole{xref,std,std-term}{table}}}} specifies a set of qualids which are displayed as records.  Use the
{\hyperref[\detokenize{language/core/basic:coq:cmd.Add}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add}}}}} and {\hyperref[\detokenize{language/core/basic:coq:cmd.Remove}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove}}}}} commands to update the set of qualids.

\end{fulllineitems}\end{savenotes}

\index{Printing Constructor (table)@\spxentry{Printing Constructor}\spxextra{table}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records:coq:table.Printing-Constructor}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Constructor~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-table}]{\sphinxtermref{\DUrole{xref,std,std-term}{table}}}} specifies a set of qualids which are displayed as constructors.  Use the
{\hyperref[\detokenize{language/core/basic:coq:cmd.Add}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add}}}}} and {\hyperref[\detokenize{language/core/basic:coq:cmd.Remove}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove}}}}} commands to update the set of qualids.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
This syntax can also be used for pattern matching.

\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}{|} \PYG{o}{\PYGZob{}|} \PYG{n}{sign} \PYG{o}{:=} \PYG{n+nb+bp}{true}\PYG{o}{;} \PYG{n}{top} \PYG{o}{:=} \PYG{n}{n} \PYG{o}{|\PYGZcb{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{n}
  \PYG{o}{|} \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{n}{nat}
\end{sphinxVerbatim}

\sphinxAtStartPar
The macro generates also, when it is possible, the projection
functions for destructuring an object of type {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. These
projection functions are given the names of the corresponding
fields. If a field is named \sphinxcode{\sphinxupquote{\_}} then no projection is built
for it. In our example:

\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{n}{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{n}{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}

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

\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{n}{nat}
\end{sphinxVerbatim}
\index{Printing Projections (flag)@\spxentry{Printing Projections}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records:coq:flag.Printing-Projections}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Projections}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} activates the dot notation for printing.

\begin{sphinxadmonition}{note}{Example}

\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{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\phantomsection\label{\detokenize{language/core/records:record-projections-grammar}}\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/records:grammar-token-term_projection}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-term_projection}]{\sphinxcrossref{\DUrole{hole}{term\_projection}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}} .( {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}\DUrole{notation-sup}{*}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}} .( @ {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term1}]{\sphinxcrossref{\DUrole{hole}{term1}}}}}\DUrole{notation-sup}{*}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Syntax of Record projections
\end{quote}

\sphinxAtStartPar
The corresponding grammar rules are given in the preceding grammar. When {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}
denotes a projection, the syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}.({\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}})}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}}}},
the syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}.({\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}\DUrole{notation-sup}{+}})}}} to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}\DUrole{notation-sup}{+}} {\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}}}}.
and the syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}.(@{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}}\DUrole{notation-sup}{+}})}}} to \sphinxcode{\sphinxupquote{\DUrole{notation}{@{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}}\DUrole{notation-sup}{+}} {\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}}}}.
In each case, {\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term0}}}}} is the object projected and the
other arguments are the parameters of the inductive type.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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\sphinxhyphen{}inductive record.
Definition of mutually inductive or co\sphinxhyphen{}inductive records are also allowed, as long
as all of the types in the block are records.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Induction schemes are automatically generated for inductive records.
Automatic generation of induction schemes for non\sphinxhyphen{}recursive records
defined with the \sphinxcode{\sphinxupquote{Record}} keyword can be activated with the
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Nonrecursive-Elimination-Schemes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Nonrecursive Elimination Schemes}}}}} flag (see {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:proofschemes-induction-principles}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Scheme}}}}).
\end{sphinxadmonition}
\index{‘ident’ cannot be defined (warning)@\spxentry{‘ident’ cannot be defined}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records:coq:warn._u2018ident_u2019-cannot-be-defined}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~cannot~be~defined.}}}}
\sphinxAtStartPar
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}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
The name {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} already exists in the global environment (see {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}}).

\item {} 
\sphinxAtStartPar
The {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} uses an incorrect elimination for
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} (see {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} and {\hyperref[\detokenize{language/core/inductive:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}).

\item {} 
\sphinxAtStartPar
The type of the projections {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} depends on previous
projections which themselves could not be defined.

\end{enumerate}

\end{fulllineitems}\end{savenotes}

\index{Records declared with the keyword Record or Structure cannot be recursive (error)@\spxentry{Records declared with the keyword Record or Structure cannot be recursive}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records: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.}}}}
\sphinxAtStartPar
The record name {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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}\end{savenotes}

\index{Cannot handle mutually (co)inductive records (error)@\spxentry{Cannot handle mutually (co)inductive records}\spxextra{error}}

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

\end{fulllineitems}\end{savenotes}


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


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
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/core/records:primitive-projections}}\label{\detokenize{language/core/records:id2}}\index{Primitive Projections (flag)@\spxentry{Primitive Projections}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records:coq:flag.Primitive-Projections}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Primitive~Projections}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} 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 \sphinxcode{\sphinxupquote{r.(p)}} representing a primitive projection \sphinxcode{\sphinxupquote{p}} applied
to a record object \sphinxcode{\sphinxupquote{r}} (i.e., primitive projections are always applied).
Even if the record type has parameters, these do not appear
in the internal representation of
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}\end{savenotes}

\index{Printing Primitive Projection Parameters (flag)@\spxentry{Printing Primitive Projection Parameters}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/records:coq:flag.Printing-Primitive-Projection-Parameters}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Primitive~Projection~Parameters}}}}
\sphinxAtStartPar
This compatibility {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} reconstructs internally omitted parameters at
printing time (even though they are absent in the actual AST manipulated
by the kernel).

\end{fulllineitems}\end{savenotes}



\paragraph{Primitive Record Types}
\label{\detokenize{language/core/records:primitive-record-types}}
\sphinxAtStartPar
When the {\hyperref[\detokenize{language/core/records:coq:flag.Primitive-Projections}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Primitive Projections}}}}} flag 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/core/records:primitive-projections}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Projections}}}} though).
To eliminate the (co\sphinxhyphen{})inductive type, one must use its defined primitive projections.

\sphinxAtStartPar
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/core/records:coq:flag.Printing-Primitive-Projection-Parameters}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Primitive Projection Parameters}}}}} flag.

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

\item {} 
\sphinxAtStartPar
Through the \sphinxcode{\sphinxupquote{Inductive}} and \sphinxcode{\sphinxupquote{CoInductive}} commands, when
the {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} of the definition is a record declaration of the form
\sphinxcode{\sphinxupquote{Build\_}}\sphinxcode{\sphinxupquote{R}} \sphinxcode{\sphinxupquote{\{}} \sphinxcode{\sphinxupquote{p}}\(_{1}\) \sphinxcode{\sphinxupquote{:}} \sphinxcode{\sphinxupquote{t}}\(_{1}\)\sphinxcode{\sphinxupquote{; … ;}} \sphinxcode{\sphinxupquote{p}}\(_{n}\) \sphinxcode{\sphinxupquote{:}} \sphinxcode{\sphinxupquote{t}}\(_{n}\) \sphinxcode{\sphinxupquote{\}}}.
In this case the types can be recursive and eta\sphinxhyphen{}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\sphinxhyphen{}dependent case analysis
can be defined.

\end{enumerate}


\paragraph{Reduction}
\label{\detokenize{language/core/records:reduction}}
\sphinxAtStartPar
The basic reduction rule of a primitive projection is
\sphinxcode{\sphinxupquote{p}}\(_{i}\) \sphinxcode{\sphinxupquote{(Build\_}}\sphinxcode{\sphinxupquote{R}} \sphinxcode{\sphinxupquote{t}}\(_{1}\) … \sphinxcode{\sphinxupquote{t}}\(_{n}\)\sphinxcode{\sphinxupquote{)}} \({\rightarrow_{\iota}}\) \sphinxcode{\sphinxupquote{t}}\(_{i}\).
However, to take the δ 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\sphinxhyphen{}reduces to the unfolded version. This allows to
precisely mimic the usual unfolding rules of {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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\sphinxhyphen{}level, and there is no way to display unfolded projections differently
from folded ones.


\paragraph{Compatibility Projections and \sphinxstyleliteralintitle{\sphinxupquote{match}}}
\label{\detokenize{language/core/records:compatibility-projections-and-match}}
\sphinxAtStartPar
To ease compatibility with ordinary record types, each primitive
projection is also defined as an ordinary {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} taking parameters and
an object of the record type as arguments, and whose {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{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 {\hyperref[\detokenize{language/core/records:coq:flag.Printing-Primitive-Projection-Parameters}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Primitive Projection Parameters}}}}} flag
is off: For a primitive projection application, parameters are printed
as underscores while for the compatibility projections they are printed
as usual.

\sphinxAtStartPar
Additionally, user\sphinxhyphen{}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{Inductive types and recursive functions}
\label{\detokenize{language/core/inductive:inductive-types-and-recursive-functions}}\label{\detokenize{language/core/inductive::doc}}

\subsubsection{Inductive types}
\label{\detokenize{language/core/inductive:inductive-types}}\label{\detokenize{language/core/inductive:gallina-inductive-definitions}}\index{Inductive (command)@\spxentry{Inductive}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:cmd.Inductive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Inductive~{\hyperref[\detokenize{language/core/inductive:grammar-token-inductive_definition}]{\sphinxcrossref{\DUrole{hole}{inductive\_definition}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/inductive:grammar-token-inductive_definition}]{\sphinxcrossref{\DUrole{hole}{inductive\_definition}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/inductive:grammar-token-inductive_definition}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-inductive_definition}]{\sphinxcrossref{\DUrole{hole}{inductive\_definition}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{>}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-cumul_univ_decl}]{\sphinxcrossref{\DUrole{hole}{cumul\_univ\_decl}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{| \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{:= \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/inductive:grammar-token-constructors_or_record}]{\sphinxcrossref{\DUrole{hole}{constructors\_or\_record}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}]{\sphinxcrossref{\DUrole{hole}{decl\_notations}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/inductive:grammar-token-constructors_or_record}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-constructors_or_record}]{\sphinxcrossref{\DUrole{hole}{constructors\_or\_record}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/inductive:grammar-token-constructor}]{\sphinxcrossref{\DUrole{hole}{constructor}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} \{ \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/records:grammar-token-record_field}]{\sphinxcrossref{\DUrole{hole}{record\_field}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}} \DUrole{repeat-wrapper}{\DUrole{repeat}{;}\DUrole{notation-sup}{?}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/inductive:grammar-token-constructor}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-constructor}]{\sphinxcrossref{\DUrole{hole}{constructor}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-of_type}]{\sphinxcrossref{\DUrole{hole}{of\_type}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
This command defines one or more
inductive types and its constructors.  Coq generates destructors
depending on the universe that the inductive type belongs to.

\sphinxAtStartPar
The destructors are named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_rect}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_ind}},
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_rec}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_sind}}, which
respectively correspond to elimination principles on \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}},
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{SProp}}}.  The type of the destructors
expresses structural induction/recursion principles over objects of
type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.  The {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_ind}} is always
generated, whereas \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_rec}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_rect}}
may be impossible to derive (for example, when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a
proposition).

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}},
{\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template)}}}}}, {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative)}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(positivity)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(positivity)}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(universes)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(universes)}}}}}, and
{\hyperref[\detokenize{language/core/variants:coq:attr.private(matching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{private(matching)}}}}} attributes.

\sphinxAtStartPar
Mutually inductive types can be defined by including multiple \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-inductive_definition}]{\sphinxcrossref{\DUrole{hole}{inductive\_definition}}}}}}}s.
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}s are simultaneously added to the global environment before the types of constructors are checked.
Each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} can be used independently thereafter.
See {\hyperref[\detokenize{language/core/inductive:mutually-inductive-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Mutually defined inductive types}}}}.

\sphinxAtStartPar
If the entire inductive definition is parameterized with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}}s, the parameters correspond
to a local context in which the entire set of inductive declarations is interpreted.
For this reason, the parameters must be strictly the same for each inductive type.
See {\hyperref[\detokenize{language/core/inductive:parametrized-inductive-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Parameterized inductive types}}}}.

\sphinxAtStartPar
Constructor \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}s can come with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}}s, in which case
the actual type of the constructor is \sphinxcode{\sphinxupquote{\DUrole{notation}{forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}, {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}.
\index{Non strictly positive occurrence of ‘ident’ in ‘type’ (error)@\spxentry{Non strictly positive occurrence of ‘ident’ in ‘type’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:exn.Non-strictly-positive-occurrence-of-_u2018ident_u2019-in-_u2018type_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Non~strictly~positive~occurrence~of~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}.}}}}
\sphinxAtStartPar
The types of the constructors have to satisfy a \sphinxstyleemphasis{positivity
condition} (see Section {\hyperref[\detokenize{language/core/inductive:positivity}]{\sphinxcrossref{\DUrole{std,std-ref}{Positivity Condition}}}}). This condition
ensures the soundness of the inductive definition.
Positivity checking can be disabled using the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Positivity-Checking}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Positivity
Checking}}}}} flag or the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(positivity)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(positivity)}}}}} attribute (see
{\hyperref[\detokenize{proof-engine/vernacular-commands:controlling-typing-flags}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling Typing Flags}}}}).

\end{fulllineitems}\end{savenotes}

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

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

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
The following subsections show examples of simple inductive types,
simple annotated inductive types, simple parametric inductive types,
mutually inductive types and private (matching) inductive types.


\paragraph{Simple inductive types}
\label{\detokenize{language/core/inductive:simple-inductive-types}}\label{\detokenize{language/core/inductive:id1}}
\sphinxAtStartPar
A simple inductive type belongs to a universe that is a simple \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}}}.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The set of natural numbers is defined as:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{nat} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{O} \PYG{o}{:} \PYG{n}{nat}
\PYG{o}{|} \PYG{n}{S} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{.}
    \PYG{n}{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}
    \PYG{n}{nat\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
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{name}{nat}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{O}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{S}}} are added to the
global environment.

\sphinxAtStartPar
This definition generates four elimination principles:
\sphinxcode{\sphinxupquote{\DUrole{name}{nat\_rect}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_ind}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_rec}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_sind}}}. The type of \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_ind}}} is:

\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{n}{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{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n}
\end{sphinxVerbatim}

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

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

\sphinxAtStartPar
In the case where inductive types don't have annotations (the next section
gives an example of annotations), a constructor can be defined
by giving the type of its arguments alone.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{nat} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{O} \PYG{o}{|} \PYG{n}{S} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Simple annotated inductive types}
\label{\detokenize{language/core/inductive:simple-annotated-inductive-types}}
\sphinxAtStartPar
In annotated inductive types, the universe where the inductive type
is defined is no longer a simple \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}}}, but what is called an arity,
which is a type whose conclusion is a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}}}.

\begin{sphinxadmonition}{note}{Example}

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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{even} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{even\PYGZus{}0} \PYG{o}{:} \PYG{n}{even} \PYG{n}{O}
\PYG{o}{|} \PYG{n}{even\PYGZus{}SS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{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}
    \PYG{n}{even\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

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

\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{n}{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{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{even} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n}
\end{sphinxVerbatim}

\sphinxAtStartPar
From a mathematical point of view, this asserts that the natural numbers satisfying
the predicate \sphinxcode{\sphinxupquote{\DUrole{name}{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 analogous to the
structural induction principle we got for \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}.
\end{sphinxadmonition}


\paragraph{Parameterized inductive types}
\label{\detokenize{language/core/inductive:parameterized-inductive-types}}\label{\detokenize{language/core/inductive:parametrized-inductive-types}}
\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}}s shared by all the constructors of the definition.

\sphinxAtStartPar
Parameters differ from inductive type annotations in that the
conclusion of each type of constructor invokes the inductive type with
the same parameter values of its specification.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
A typical example is the definition of polymorphic lists:

\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}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}
\PYG{o}{|} \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}{.}
    \PYG{n}{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{n}{list\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
In the type of \sphinxcode{\sphinxupquote{\DUrole{name}{nil}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{cons}}}, we write "\sphinxcode{\sphinxupquote{\DUrole{name}{list} \DUrole{name}{A}}}" and not
just "\sphinxcode{\sphinxupquote{\DUrole{name}{list}}}". The constructors \sphinxcode{\sphinxupquote{\DUrole{name}{nil}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{cons}}} have these types:

\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{n}{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{n}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{n}{A}
\end{sphinxVerbatim}

\sphinxAtStartPar
Observe that the destructors are also quantified with \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,namespace}{Set}\DUrole{operator}{)}}}, for example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{list\PYGZus{}ind}\PYG{o}{.}
    \PYG{n}{list\PYGZus{}ind}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
           \PYG{n}{P} \PYG{o}{(}\PYG{n}{nil} \PYG{n}{A}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{a} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{A} \PYG{n}{a} \PYG{n}{l}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}\PYG{o}{,} \PYG{n}{P} \PYG{n}{l}
\end{sphinxVerbatim}

\sphinxAtStartPar
Once again, the names of the constructor arguments and the type of the conclusion can be omitted:

\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{n}{nil} \PYG{o}{|} \PYG{n}{cons} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{list} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
\sphinxAtStartPar
The constructor type can
recursively invoke the inductive definition on an argument which is not
the parameter itself.

\sphinxAtStartPar
One can define :

\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}{|} \PYG{n}{nil2} \PYG{o}{:} \PYG{n}{list2} \PYG{n}{A}
\PYG{o}{|} \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}
    \PYG{n}{list2\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

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

\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}{|} \PYG{n}{nil2}
\PYG{o}{|} \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}
    \PYG{n}{list2\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
But the following definition will give an error:

\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}{|} \PYG{n}{nilw} \PYG{o}{:} \PYG{n}{listw} \PYG{o}{(}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{)}
\PYG{o}{|} \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}{In} \PYG{n}{environment}
    \PYG{n}{listw} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}
    \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}
    \PYG{n}{Unable} \PYG{n}{to} \PYG{n}{unify} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{listw (A * A)\PYGZpc{}type}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{with} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{listw A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

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

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

\end{itemize}
\end{sphinxadmonition}
\index{Uniform Inductive Parameters (flag)@\spxentry{Uniform Inductive Parameters}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:flag.Uniform-Inductive-Parameters}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Uniform~Inductive~Parameters}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is set (it is off by default),
inductive definitions are abstracted over their parameters
before type checking constructors, allowing to write:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Uniform} \PYG{k+kn}{Inductive} \PYG{k+kn}{Parameters}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{list3} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{nil3} \PYG{o}{:} \PYG{n}{list3}
\PYG{o}{|} \PYG{n}{cons3} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list3}\PYG{o}{.}
    \PYG{n}{list3} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list3\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list3\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list3\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list3\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
This behavior is essentially equivalent to starting a new section
and using {\hyperref[\detokenize{language/core/sections:coq:cmd.Context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Context}}}}} to give the uniform parameters, like so
(cf. {\hyperref[\detokenize{language/core/sections:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{list3}\PYG{o}{.}
\PYG{k+kn}{Context} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{A} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Inductive} \PYG{n}{list3} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{nil3} \PYG{o}{:} \PYG{n}{list3}
\PYG{o}{|} \PYG{n}{cons3} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list3}\PYG{o}{.}
    \PYG{n}{list3} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list3\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list3\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list3\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list3\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{list3}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
For finer control, you can use a \sphinxcode{\sphinxupquote{|}} between the uniform and
the non\sphinxhyphen{}uniform parameters:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Acc} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\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{o}{|} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop}
  \PYG{o}{:=} \PYG{n}{Acc\PYGZus{}in} \PYG{o}{:} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{y}\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}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The flag can then be seen as deciding whether the \sphinxcode{\sphinxupquote{|}} is at the
beginning (when the flag is unset) or at the end (when it is set)
of the parameters when not explicitly given.

\end{fulllineitems}\end{savenotes}



\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
Section {\hyperref[\detokenize{language/core/inductive:inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Theory of inductive definitions}}}} and the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} tactic.




\paragraph{Mutually defined inductive types}
\label{\detokenize{language/core/inductive:mutually-defined-inductive-types}}\label{\detokenize{language/core/inductive:mutually-inductive-types}}
\begin{sphinxadmonition}{note}{Example: Mutually defined inductive types}

\sphinxAtStartPar
A typical example of mutually inductive data types is trees and
forests. We assume two types \sphinxcode{\sphinxupquote{\DUrole{name}{A}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} that are given as variables. The types can
be declared like this:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameters} \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}{|} \PYG{n}{leaf} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest}
\PYG{o}{|} \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}

\sphinxAtStartPar
This declaration automatically generates eight induction principles. They are not the most
general principles, but they correspond to each inductive part seen as a single inductive definition.

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

\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}

\sphinxAtStartPar
Assume we want to parameterize 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 as follows:

\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}{|} \PYG{n}{leaf} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{n}{A} \PYG{n}{B}
\PYG{o}{|} \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}

\sphinxAtStartPar
Assume we define an inductive definition inside a section
(cf. {\hyperref[\detokenize{language/core/sections: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:}
\nopagebreak


\sphinxAtStartPar
A generic command {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Scheme}}}}} is useful to build automatically various
mutual induction principles.



\index{fix@\spxentry{fix}}\ignorespaces 

\subsubsection{Recursive functions: fix}
\label{\detokenize{language/core/inductive:recursive-functions-fix}}\label{\detokenize{language/core/inductive:index-0}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/inductive:grammar-token-term_fix}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-term_fix}]{\sphinxcrossref{\DUrole{hole}{term\_fix}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let fix {\hyperref[\detokenize{language/core/inductive:grammar-token-fix_decl}]{\sphinxcrossref{\DUrole{hole}{fix\_decl}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{fix {\hyperref[\detokenize{language/core/inductive:grammar-token-fix_decl}]{\sphinxcrossref{\DUrole{hole}{fix\_decl}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{language/core/inductive:grammar-token-fix_decl}]{\sphinxcrossref{\DUrole{hole}{fix\_decl}}}}}\DUrole{notation-sup}{+}} for {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/inductive:grammar-token-fix_decl}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_decl}]{\sphinxcrossref{\DUrole{hole}{fix\_decl}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/inductive:grammar-token-fixannot}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ struct {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ wf {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ measure {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The expression "\sphinxcode{\sphinxupquote{\DUrole{notation}{fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{1}}$}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} with … with {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{n}}$}}}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder$_{\text{n}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{n}}$}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{n}}$}}}} for {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}}" denotes the
\(i\)\sphinxhyphen{}th component of a block of functions defined by mutual structural
recursion. It is the local counterpart of the {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} command. When
\(n=1\), the "\sphinxcode{\sphinxupquote{\DUrole{notation}{for {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}}" clause is omitted.

\sphinxAtStartPar
The association of a single fixpoint and a local definition have a special
syntax: \sphinxcode{\sphinxupquote{\DUrole{notation}{let fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in}}} stands for
\sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in}}}. The same applies for co\sphinxhyphen{}fixpoints.

\sphinxAtStartPar
Some options of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}}} are only supported in specific constructs.  \sphinxcode{\sphinxupquote{\DUrole{notation}{fix}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{let fix}}}
only support the \sphinxcode{\sphinxupquote{\DUrole{notation}{struct}}} option, while \sphinxcode{\sphinxupquote{\DUrole{notation}{wf}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{measure}}} are only supported in
commands such as {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} (with the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute) and {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}.


\subsubsection{Top\sphinxhyphen{}level recursive functions}
\label{\detokenize{language/core/inductive:top-level-recursive-functions}}\label{\detokenize{language/core/inductive:fixpoint}}
\sphinxAtStartPar
This section describes the primitive form of definition by recursion over
inductive objects. See the {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} command for more advanced
constructions.
\index{Fixpoint (command)@\spxentry{Fixpoint}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:cmd.Fixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Fixpoint~{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_definition}]{\sphinxcrossref{\DUrole{hole}{fix\_definition}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_definition}]{\sphinxcrossref{\DUrole{hole}{fix\_definition}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/inductive:grammar-token-fix_definition}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_definition}]{\sphinxcrossref{\DUrole{hole}{fix\_definition}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{:= {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}]{\sphinxcrossref{\DUrole{hole}{decl\_notations}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Allows defining functions by pattern matching over inductive
objects using a fixed point construction. The meaning of this declaration is
to define \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} as a recursive function with arguments specified by
the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}}s such that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} applied to arguments
corresponding to these \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}}s has type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}, and is
equivalent to the expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. The type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is
consequently \sphinxcode{\sphinxupquote{\DUrole{notation}{forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}, {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} and its value is equivalent
to \sphinxcode{\sphinxupquote{\DUrole{notation}{fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\sphinxAtStartPar
This command accepts the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(universes)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(universes)}}}}}, and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(guard)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(guard)}}}}} attributes.

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

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

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} without the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute does not support the
\sphinxcode{\sphinxupquote{\DUrole{notation}{wf}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{measure}}} clauses of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}}}. See {\hyperref[\detokenize{addendum/program:program-fixpoint}]{\sphinxcrossref{\DUrole{std,std-ref}{Program Fixpoint}}}}.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{with}}} clause allows simultaneously defining several mutual fixpoints.
It is especially useful when defining functions over mutually defined
inductive types.  Example: {\hyperref[\detokenize{language/core/inductive:example-mutual-fixpoints}]{\sphinxcrossref{\DUrole{std,std-ref}{Mutual Fixpoints}}}}.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is omitted, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} is required and Coq enters proof mode.
This can be used to define a term incrementally, in particular by relying on the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic.
In this case, the proof should be terminated with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}} in order to define a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}}
for which the computational behavior is relevant.  See {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Entering and exiting proof mode}}}}.

\sphinxAtStartPar
This command accepts the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:attr.using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{using}}}}} attribute.

\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
One can define the addition function as :

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{add} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
\PYG{o}{|} \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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}{))}}}.

\sphinxAtStartPar
The match operator is formally described in
Section {\hyperref[\detokenize{language/core/inductive: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}

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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Fixpoint} \PYG{n}{wrongplus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{n}
\PYG{o}{|} \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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}
    \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}
    \PYG{n}{p} \PYG{o}{:} \PYG{n}{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}{                      | 0 =\PYGZgt{} n}
\PYG{l+s+s2}{                      | S p =\PYGZgt{} S (wrongplus n p)}
\PYG{l+s+s2}{                      end}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{n}
\PYG{o}{|} \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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{mod2} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
\PYG{o}{|} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{p} \PYG{k}{with}
         \PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{O}
         \PYG{o}{|} \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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\phantomsection\label{\detokenize{language/core/inductive:example-mutual-fixpoints}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Mutual fixpoints}

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

\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{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{t} \PYG{k}{with}
\PYG{o}{|} \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{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{leaf} \PYG{n}{b} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{1}
\PYG{o}{|} \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}{guarded} \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{quote}


\subsubsection{Theory of inductive definitions}
\label{\detokenize{language/core/inductive:theory-of-inductive-definitions}}\label{\detokenize{language/core/inductive:inductive-definitions}}
\sphinxAtStartPar
Formally, we can represent any \sphinxstyleemphasis{inductive definition} as
\(\ind{p}{Γ_I}{Γ_C}\) where:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\(Γ_I\) determines the names and types of inductive types;

\item {} 
\sphinxAtStartPar
\(Γ_C\) determines the names and types of constructors of these
inductive types;

\item {} 
\sphinxAtStartPar
\(p\) determines the number of parameters of these inductive types.

\end{itemize}

\sphinxAtStartPar
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}

\sphinxAtStartPar
The declaration for parameterized lists is:
\begin{equation*}
\begin{split}\ind{1}{[\List:\Set→\Set]}{\left[\begin{array}{rcl}
\Nil & : & ∀ A:\Set,~\List~A \\
\cons & : & ∀ A:\Set,~A→ \List~A→ \List~A
\end{array}
\right]}\end{split}
\end{equation*}
\sphinxAtStartPar
which corresponds to the result of the Coq declaration:

\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}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}
\PYG{o}{|} \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}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
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*}
\sphinxAtStartPar
which corresponds to the result of the Coq declaration:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{tree} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \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}{|} \PYG{n}{emptyf} \PYG{o}{:} \PYG{n}{forest}
\PYG{o}{|} \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}

\sphinxAtStartPar
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 &:& ∀ n,~\odd~n → \even~(\nS~n)\\
          \oddS &:& ∀ n,~\even~n → \odd~(\nS~n)
                    \end{array}\right]}\end{split}
\end{equation*}
\sphinxAtStartPar
which corresponds to the result of the Coq declaration:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{even} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{even\PYGZus{}O} \PYG{o}{:} \PYG{n}{even} \PYG{l+m+mi}{0}
\PYG{o}{|} \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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{|} \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}


\paragraph{Types of inductive objects}
\label{\detokenize{language/core/inductive:types-of-inductive-objects}}\label{\detokenize{language/core/inductive:id2}}
\sphinxAtStartPar
We have to give the type of constants in a global environment \(E\) which
contains an inductive definition.
\begin{description}
\phantomsection\label{\detokenize{language/core/inductive: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/core/inductive: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}

\sphinxAtStartPar
Provided that our global 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[Γ] ⊢ \evenO : \even~\nO\\
E[Γ] ⊢ \evenS : ∀ n:\nat,~\odd~n → \even~(\nS~n)\\
E[Γ] ⊢ \oddS : ∀ n:\nat,~\even~n → \odd~(\nS~n)
\end{array}\end{split}
\end{equation*}\end{sphinxadmonition}


\paragraph{Well\sphinxhyphen{}formed inductive definitions}
\label{\detokenize{language/core/inductive:well-formed-inductive-definitions}}\label{\detokenize{language/core/inductive:id3}}
\sphinxAtStartPar
We cannot accept any inductive definition because some of them lead
to inconsistent systems. We restrict ourselves to definitions which
satisfy a syntactic criterion of positivity. Before giving the formal
rules, we need a few definitions:


\subparagraph{Arity of a given sort}
\label{\detokenize{language/core/inductive:arity-of-a-given-sort}}
\sphinxAtStartPar
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}

\sphinxAtStartPar
\(A→\Set\) is an arity of sort \(\Set\). \(∀ A:\Prop,~A→ \Prop\) is an arity of sort
\(\Prop\).
\end{sphinxadmonition}


\subparagraph{Arity}
\label{\detokenize{language/core/inductive:arity}}
\sphinxAtStartPar
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}

\sphinxAtStartPar
\(A→ \Set\) and \(∀ A:\Prop,~A→ \Prop\) are arities.
\end{sphinxadmonition}


\subparagraph{Type of constructor}
\label{\detokenize{language/core/inductive:type-of-constructor}}
\sphinxAtStartPar
We say that \(T\) is a \sphinxstyleemphasis{type of constructor of} \(I\) in one of the following
two cases:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\(T\) is \((I~t_1 … t_n )\)

\item {} 
\sphinxAtStartPar
\(T\) is \(∀ x:U,~T'\) where \(T'\) is also a type of constructor of \(I\)

\end{itemize}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
\(\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}


\subparagraph{Positivity Condition}
\label{\detokenize{language/core/inductive:positivity-condition}}\label{\detokenize{language/core/inductive:positivity}}
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
\(T=(X~t_1 … t_n )\) and \(X\) does not occur free in any \(t_i\)

\item {} 
\sphinxAtStartPar
\(T=∀ x:U,~V\) and \(X\) occurs only strictly positively in \(U\) and the type \(V\)
satisfies the positivity condition for \(X\).

\end{itemize}


\subparagraph{Strict positivity}
\label{\detokenize{language/core/inductive:strict-positivity}}
\sphinxAtStartPar
The constant \(X\) \sphinxstyleemphasis{occurs strictly positively} in \(T\) in the following
cases:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\(X\) does not occur in \(T\)

\item {} 
\sphinxAtStartPar
\(T\) converts to \((X~t_1 … t_n )\) and \(X\) does not occur in any of \(t_i\)

\item {} 
\sphinxAtStartPar
\(T\) converts to \(∀ x:U,~V\) and \(X\) does not occur in type \(U\) but occurs
strictly positively in type \(V\)

\item {} 
\sphinxAtStartPar
\(T\) converts to \((I~a_1 … a_m~t_1 … t_p )\) where \(I\) is the name of an
inductive definition 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*}
\sphinxAtStartPar
(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}


\subparagraph{Nested Positivity}
\label{\detokenize{language/core/inductive:nested-positivity}}
\sphinxAtStartPar
The type of constructor \(T\) of \(I\) \sphinxstyleemphasis{satisfies the nested positivity
condition} for a constant \(X\) in the following cases:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\(T=(I~b_1 … b_m~u_1 … u_p)\), \(I\) is an inductive type with \(m\)
parameters and \(X\) does not occur in any \(u_i\)

\item {} 
\sphinxAtStartPar
\(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}

\sphinxAtStartPar
For instance, if one considers the following variant of a tree type
branching over the natural numbers:

\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}{|} \PYG{n}{leaf} \PYG{o}{:} \PYG{n}{nattree} \PYG{n}{A}
\PYG{o}{|} \PYG{n}{natnode} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{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}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Then every instantiated constructor of \sphinxcode{\sphinxupquote{nattree A}} satisfies the nested positivity
condition for \sphinxcode{\sphinxupquote{nattree}}:
\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
Type \sphinxcode{\sphinxupquote{A → (nat → nattree A) → nattree A}} of constructor \sphinxcode{\sphinxupquote{natnode}} satisfies the
positivity condition for \sphinxcode{\sphinxupquote{nattree}} because:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{nattree}} occurs only strictly positively in \sphinxcode{\sphinxupquote{A}} ... (bullet 1)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{nattree}} occurs only strictly positively in \sphinxcode{\sphinxupquote{nat → nattree A}} ... (bullet 3 + 2)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{nattree}} satisfies the positivity condition for \sphinxcode{\sphinxupquote{nattree A}} ... (bullet 1)

\end{itemize}

\end{itemize}
\end{sphinxadmonition}


\subparagraph{Correctness rules}
\label{\detokenize{language/core/inductive:correctness-rules}}\label{\detokenize{language/core/inductive:id4}}
\sphinxAtStartPar
We shall now describe the rules allowing the introduction of a new
inductive definition.

\sphinxAtStartPar
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/core/inductive:inference-W-Ind}}\item[{W\sphinxhyphen{}Ind}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{Γ_P}%
\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}

\sphinxAtStartPar
provided that the following side conditions hold:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\(k>0\) and all of \(I_j\) and \(c_i\) are distinct names for \(j=1… k\) and \(i=1… n\),

\item {} 
\sphinxAtStartPar
\(p\) is the number of parameters of \(\ind{p}{Γ_I}{Γ_C}\) and \(Γ_P\) is the
context of parameters,

\item {} 
\sphinxAtStartPar
for \(j=1… k\) we have that \(A_j\) is an arity of sort \(s_j\) and \(I_j ∉ E\),

\item {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
One can remark that there is a constraint between the sort of the
arity of the inductive type and the sort of the type of its
constructors which will always be satisfied for the impredicative
sorts \(\SProp\) and \(\Prop\) but may fail to define
inductive type on sort \(\Set\) and generate constraints
between universes for inductive types in the Type hierarchy.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
It is well known that the existential quantifier can be encoded as an
inductive definition. The following declaration introduces the
second\sphinxhyphen{}order existential quantifier \(∃ X.P(X)\).

\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}{|} \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}

\sphinxAtStartPar
The same definition on \(\Set\) is not allowed and fails:

\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}

\sphinxAtStartPar
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\).

\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}
    \PYG{n}{exType\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: Negative occurrence (first example)}

\sphinxAtStartPar
The following inductive definition is rejected because it does not
satisfy the positivity condition:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Inductive} \PYG{n}{I} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{not\PYGZus{}I\PYGZus{}I} \PYG{o}{(}\PYG{n}{not\PYGZus{}I} \PYG{o}{:} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}\PYG{o}{)} \PYG{o}{:} \PYG{n}{I}\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}{Non} \PYG{n}{strictly} \PYG{n}{positive} \PYG{n}{occurrence} \PYG{k}{of} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{I}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{in} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(I \PYGZhy{}\PYGZgt{} False) \PYGZhy{}\PYGZgt{} I}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
If we were to accept such definition, we could derive a
contradiction from it (we can test this by disabling the
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Positivity-Checking}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Positivity Checking}}}}} flag):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{I\PYGZus{}not\PYGZus{}I} \PYG{o}{:} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{I} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{i} \PYG{o}{=\PYGZgt{}}
  \PYG{k}{match} \PYG{n}{i} \PYG{k}{with} \PYG{n}{not\PYGZus{}I\PYGZus{}I} \PYG{n}{not\PYGZus{}I} \PYG{o}{=\PYGZgt{}} \PYG{n}{not\PYGZus{}I} \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{I\PYGZus{}not\PYGZus{}I} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{k+kp}{contradiction} \PYG{o}{:} \PYG{n}{False}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
  \PYG{n}{enough} \PYG{o}{(}\PYG{n}{I} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZti{}} \PYG{n}{I}\PYG{o}{)} \PYG{k}{as} \PYG{n+nb+bp}{[]} \PYG{k+kp}{by} \PYG{k+kp}{contradiction}\PYG{o}{.}
  \PYG{k}{split}\PYG{o}{.}
  \PYG{o}{\PYGZhy{}} \PYG{k}{apply} \PYG{n}{not\PYGZus{}I\PYGZus{}I}\PYG{o}{.}
    \PYG{k}{intro}\PYG{o}{.}
    \PYG{n}{now} \PYG{k}{apply} \PYG{n}{I\PYGZus{}not\PYGZus{}I}\PYG{o}{.}
  \PYG{o}{\PYGZhy{}} \PYG{k}{intro}\PYG{o}{.}
    \PYG{n}{now} \PYG{k}{apply} \PYG{n}{I\PYGZus{}not\PYGZus{}I}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: Negative occurrence (second example)}

\sphinxAtStartPar
Here is another example of an inductive definition which is
rejected because it does not satify the positivity condition:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Inductive} \PYG{n}{Lam} \PYG{o}{:=} \PYG{n}{lam} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{Lam} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Lam}\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}{Non} \PYG{n}{strictly} \PYG{n}{positive} \PYG{n}{occurrence} \PYG{k}{of} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Lam}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{in} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(Lam \PYGZhy{}\PYGZgt{} Lam) \PYGZhy{}\PYGZgt{} Lam}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Again, if we were to accept it, we could derive a contradiction
(this time through a non\sphinxhyphen{}terminating recursive function):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{infinite\PYGZus{}loop} \PYG{n}{l} \PYG{o}{:} \PYG{n}{False} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with} \PYG{n}{lam} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{infinite\PYGZus{}loop} \PYG{o}{(}\PYG{n}{x} \PYG{n}{l}\PYG{o}{)} \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{infinite\PYGZus{}loop} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{infinite\PYGZus{}loop} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}


\PYG{k+kn}{Check} \PYG{n}{infinite\PYGZus{}loop} \PYG{o}{(}\PYG{n}{lam} \PYG{o}{(}\PYG{o}{@}\PYG{n}{id} \PYG{n}{Lam}\PYG{o}{)}\PYG{o}{)} \PYG{o}{:} \PYG{n}{False}\PYG{o}{.}
    \PYG{n}{infinite\PYGZus{}loop} \PYG{o}{(}\PYG{n}{lam} \PYG{o}{(}\PYG{n}{id} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{Lam}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{o}{:} \PYG{n}{False}
         \PYG{o}{:} \PYG{n}{False}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: Non strictly positive occurrence}

\sphinxAtStartPar
It is less obvious why inductive type definitions with occurences
that are positive but not strictly positive are harmful.
We will see that in presence of an impredicative type they
are unsound:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Inductive} \PYG{n}{A}\PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n}{introA}\PYG{o}{:} \PYG{o}{(}\PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\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}{Non} \PYG{n}{strictly} \PYG{n}{positive} \PYG{n}{occurrence} \PYG{k}{of} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{in} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{((A \PYGZhy{}\PYGZgt{} Prop) \PYGZhy{}\PYGZgt{} Prop) \PYGZhy{}\PYGZgt{} A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
If we were to accept this definition we could derive a contradiction
by creating an injective function from \(A → \Prop\) to \(A\).

\sphinxAtStartPar
This function is defined by composing the injective constructor of
the type \(A\) with the function \(λx. λz. z = x\) injecting
any type \(T\) into \(T → \Prop\).

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{:} \PYG{n}{A} \PYG{o}{:=} \PYG{n}{introA} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{z} \PYG{o}{=\PYGZgt{}} \PYG{n}{z} \PYG{o}{=} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{f\PYGZus{}inj}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n}{f} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
  \PYG{k}{unfold} \PYG{n}{f}\PYG{o}{;} \PYG{k}{intros} \PYG{o}{?} \PYG{o}{?} \PYG{n}{H}\PYG{o}{;} \PYG{k}{injection} \PYG{n}{H}\PYG{o}{.}
  \PYG{k}{set} \PYG{o}{(}\PYG{n}{F} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{z} \PYG{o}{=\PYGZgt{}} \PYG{n}{z} \PYG{o}{=} \PYG{n}{y}\PYG{o}{)}\PYG{o}{;} \PYG{k}{intro} \PYG{n}{HF}\PYG{o}{.}
  \PYG{k}{symmetry}\PYG{o}{;} \PYG{k}{replace} \PYG{o}{(}\PYG{n}{y} \PYG{o}{=} \PYG{n}{x}\PYG{o}{)} \PYG{k}{with} \PYG{o}{(}\PYG{n}{F} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
  \PYG{o}{+} \PYG{k}{unfold} \PYG{n}{F}\PYG{o}{;} \PYG{k+kp}{reflexivity}\PYG{o}{.}
  \PYG{o}{+} \PYG{k}{rewrite} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{HF}\PYG{o}{;} \PYG{k+kp}{reflexivity}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The type \(A → \Prop\) can be understood as the powerset
of the type \(A\). To derive a contradiction from the
injective function \(f\) we use Cantor's classic diagonal
argument.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{d}\PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{k}{exists} \PYG{n}{s}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{n}{f} \PYG{n}{s} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZti{}}\PYG{n}{s} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{d} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{fd}\PYG{o}{:} \PYG{n}{A} \PYG{o}{:=} \PYG{n}{f} \PYG{n}{d}\PYG{o}{.}
    \PYG{n}{fd} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{cantor}\PYG{o}{:} \PYG{o}{(}\PYG{n}{d} \PYG{n}{fd}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{(}\PYG{n}{d} \PYG{n}{fd}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
  \PYG{k}{split}\PYG{o}{.}
  \PYG{o}{+} \PYG{k}{intros} \PYG{o}{[}\PYG{n}{s} \PYG{o}{[}\PYG{n}{H1} \PYG{n}{H2}\PYG{o}{]}\PYG{o}{]}\PYG{o}{;} \PYG{k}{unfold} \PYG{n}{fd} \PYG{k}{in} \PYG{n}{H1}\PYG{o}{.}
    \PYG{k}{replace} \PYG{n}{d} \PYG{k}{with} \PYG{n}{s}\PYG{o}{.}
    \PYG{o}{*} \PYG{k+kp}{assumption}\PYG{o}{.}
    \PYG{o}{*} \PYG{k}{apply} \PYG{n}{f\PYGZus{}inj}\PYG{o}{;} \PYG{k+kp}{congruence}\PYG{o}{.}
  \PYG{o}{+} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{exists} \PYG{n}{d}\PYG{o}{;} \PYG{k}{tauto}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}

\PYG{k+kn}{Lemma} \PYG{n}{bad}\PYG{o}{:} \PYG{n}{False}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
  \PYG{k}{pose} \PYG{n}{cantor}\PYG{o}{;} \PYG{k}{tauto}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This derivation was first presented by Thierry Coquand and Christine
Paulin in {[}\hyperlink{cite.zebibliography:id14}{CP90}{]}.
\end{sphinxadmonition}


\subparagraph{Template polymorphism}
\label{\detokenize{language/core/inductive:template-polymorphism}}\label{\detokenize{language/core/inductive:id6}}
\sphinxAtStartPar
Inductive types can be made polymorphic over the universes introduced by
their parameters in \(\Type\), if the minimal inferred sort of the
inductive declarations either mention some of those parameter universes
or is computed to be \(\Prop\) or \(\Set\).

\sphinxAtStartPar
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\sphinxhyphen{}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.

\sphinxAtStartPar
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\sphinxhyphen{}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/core/inductive:inference-Ind-Family}}\item[{Ind\sphinxhyphen{}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}

\sphinxAtStartPar
provided that the following side conditions hold:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\(Γ_{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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
the sorts \(s_i\) are all introduced by the inductive
declaration and have no universe constraints beside being greater
than or equal to \(\Prop\), and such that all
eliminations, to \(\Prop\), \(\Set\) and \(\Type(j)\),
are allowed (see Section {\hyperref[\detokenize{language/core/inductive:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}).

\end{itemize}

\sphinxAtStartPar
Notice that if \(I_j~q_1 … q_r\) is typable using the rules \sphinxstylestrong{Ind\sphinxhyphen{}Const} and
\sphinxstylestrong{App}, then it is typable using the rule \sphinxstylestrong{Ind\sphinxhyphen{}Family}. Conversely, the
extended theory is not stronger than the theory without \sphinxstylestrong{Ind\sphinxhyphen{}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\sphinxhyphen{}formed
implies that \(\ind{p}{Γ_{I'}}{Γ_{C'}}\) is well\sphinxhyphen{}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}\).

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The restriction that sorts are introduced by the inductive
declaration prevents inductive types declared in sections to be
template\sphinxhyphen{}polymorphic on universes introduced previously in the
section: they cannot parameterize over the universes introduced with
section variables that become parameters at section closing time, as
these may be shared with other definitions from the same section
which can impose constraints on them.
\end{sphinxadmonition}
\index{Auto Template Polymorphism (flag)@\spxentry{Auto Template Polymorphism}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:flag.Auto-Template-Polymorphism}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Auto~Template~Polymorphism}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}, enabled by default, makes every inductive type declared
at level \(\Type\) (without annotations or hiding it behind a
definition) template polymorphic if possible.

\sphinxAtStartPar
This can be prevented using the {\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template=no)}}}}}
attribute.

\sphinxAtStartPar
Template polymorphism and full universe polymorphism (see Chapter
{\hyperref[\detokenize{addendum/universe-polymorphism:polymorphicuniverses}]{\sphinxcrossref{\DUrole{std,std-ref}{Polymorphic Universes}}}}) are incompatible, so if the latter is
enabled (through the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}} flag or the
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}} attribute) it will prevail over
automatic template polymorphism.

\end{fulllineitems}\end{savenotes}

\index{Automatically declaring ‘ident’ as template polymorphic (warning)@\spxentry{Automatically declaring ‘ident’ as template polymorphic}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:warn.Automatically-declaring-_u2018ident_u2019-as-template-polymorphic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Automatically~declaring~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~template~polymorphic.}}}}
\sphinxAtStartPar
Warning \sphinxcode{\sphinxupquote{auto\sphinxhyphen{}template}} can be used (it is off by default) to
find which types are implicitly declared template polymorphic by
{\hyperref[\detokenize{language/core/inductive:coq:flag.Auto-Template-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Auto Template Polymorphism}}}}}.

\sphinxAtStartPar
An inductive type can be forced to be template polymorphic using
the {\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template)}}}}} attribute: in this case, the
warning is not emitted.

\end{fulllineitems}\end{savenotes}

\index{universes(template) (attribute)@\spxentry{universes(template)}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:attr.universes(template)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{universes(template\DUrole{repeat-wrapper}{\DUrole{repeat}{=~\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}})}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{boolean attribute}}}} can be used to explicitly declare an
inductive type as template polymorphic, whether the {\hyperref[\detokenize{language/core/inductive:coq:flag.Auto-Template-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Auto
Template Polymorphism}}}}} flag is on or off.
\index{template and polymorphism not compatible (error)@\spxentry{template and polymorphism not compatible}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:exn.template-and-polymorphism-not-compatible}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{template~and~polymorphism~not~compatible}}}}
\sphinxAtStartPar
This attribute cannot be used in a full universe polymorphic
context, i.e. if the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}} flag is on or
if the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}} attribute is used.

\end{fulllineitems}\end{savenotes}

\index{Ill\sphinxhyphen{}formed template inductive declaration: not polymorphic on any universe (error)@\spxentry{Ill\sphinxhyphen{}formed template inductive declaration: not polymorphic on any universe}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:exn.Ill-formed-template-inductive-declaration:-not-polymorphic-on-any-universe}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ill\sphinxhyphen{}formed~template~inductive~declaration:~not~polymorphic~on~any~universe.}}}}
\sphinxAtStartPar
The attribute was used but the inductive definition does not
satisfy the criterion to be template polymorphic.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
When \sphinxcode{\sphinxupquote{universes(template=no)}} is used, it will prevent an
inductive type to be template polymorphic, even if the {\hyperref[\detokenize{language/core/inductive:coq:flag.Auto-Template-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Auto
Template Polymorphism}}}}} flag is on.

\end{fulllineitems}\end{savenotes}

\index{universes(notemplate) (attribute)@\spxentry{universes(notemplate)}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/inductive:coq:attr.universes(notemplate)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{universes(notemplate)}}}}~
\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.13: }Use {\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template=no)}}}}} instead.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
In practice, the rule \sphinxstylestrong{Ind\sphinxhyphen{}Family} is used by Coq only when all the
inductive types of the inductive definition are declared with an arity
whose sort is in the Type hierarchy. Then, the polymorphism is over
the parameters whose type is an arity of sort in the Type hierarchy.
The sorts \(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 – see Section {\hyperref[\detokenize{language/core/inductive:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}) is set in \(\Prop\), a small non\sphinxhyphen{}singleton
inductive type is set in \(\Set\) (even in case \(\Set\) is impredicative – see
{\hyperref[\detokenize{language/cic:the-calculus-of-inductive-construction-with-impredicative-set}]{\sphinxcrossref{\DUrole{std,std-ref}{The Calculus of Inductive Constructions with impredicative Set}}}}),
and otherwise in the Type hierarchy.

\sphinxAtStartPar
Note that the side\sphinxhyphen{}condition about allowed elimination sorts in the rule
\sphinxstylestrong{Ind\sphinxhyphen{}Family} avoids to recompute the allowed elimination sorts at each
instance of a pattern matching (see Section {\hyperref[\detokenize{language/core/inductive:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}). As an
example, let us consider the following definition:

\begin{sphinxadmonition}{note}{Example}

\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}{|} \PYG{n}{None} \PYG{o}{:} \PYG{n}{option} \PYG{n}{A}
\PYG{o}{|} \PYG{n}{Some} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{option} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
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/core/inductive: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}

\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}

\sphinxAtStartPar
Here is another example.

\begin{sphinxadmonition}{note}{Example}

\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}

\sphinxAtStartPar
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}

\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:}
\sphinxAtStartPar
Template polymorphism used to be called “sort\sphinxhyphen{}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}


\paragraph{Destructors}
\label{\detokenize{language/core/inductive:destructors}}\label{\detokenize{language/core/inductive:id7}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
For instance, assuming a parameter \(A:\Set\) exists in the local context,
we want to build a function \(\length\) of type \(\List~A → \nat\) which computes
the length of the list, such that \((\length~(\Nil~A)) = \nO\) and
\((\length~(\cons~A~a~l)) = (\nS~(\length~l))\).
We want these equalities to be
recognized implicitly and taken into account in the conversion rule.

\sphinxAtStartPar
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 type it is enough
to enumerate all the cases where \(m\) starts with a different
constructor.

\sphinxAtStartPar
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
\(∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l))\) it is enough to prove:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\((\kw{has}\_\kw{length}~A~(\Nil~A)~(\length~(\Nil~A)))\)

\item {} 
\sphinxAtStartPar
\(∀ a:A,~∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l)) →\)
\((\kw{has}\_\kw{length}~A~(\cons~A~a~l)~(\length~(\cons~A~a~l)))\)

\end{itemize}

\sphinxAtStartPar
which given the conversion equalities satisfied by \(\length\) is the same
as proving:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\((\kw{has}\_\kw{length}~A~(\Nil~A)~\nO)\)

\item {} 
\sphinxAtStartPar
\(∀ a:A,~∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l)) →\)
\((\kw{has}\_\kw{length}~A~(\cons~A~a~l)~(\nS~(\length~l)))\)

\end{itemize}

\sphinxAtStartPar
One conceptually simple way to do that, following the basic scheme
proposed by Martin\sphinxhyphen{}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.

\sphinxAtStartPar
But this operator is rather tedious to implement and use. We choose in
this version of Coq to factorize the operator for primitive recursion
into two more primitive operations as was first suggested by Th.
Coquand in {[}\hyperlink{cite.zebibliography:id12}{Coq92}{]}. One is the definition by pattern matching. The
second one is a definition by guarded fixpoints.


\subparagraph{The match ... with ... end construction}
\label{\detokenize{language/core/inductive:the-match-with-end-construction}}\label{\detokenize{language/core/inductive:match-construction}}
\sphinxAtStartPar
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 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*}
\sphinxAtStartPar
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\)\sphinxhyphen{}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 ι\sphinxhyphen{}reduction.

\sphinxAtStartPar
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\)\sphinxhyphen{}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\). 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*}
\sphinxAtStartPar
The \(\as\) part can be omitted if either the result type does not depend
on \(m\) (non\sphinxhyphen{}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/core/inductive:allowed-elimination-sorts}}
\sphinxAtStartPar
\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\sphinxhyphen{}construct.

\phantomsection\label{\detokenize{language/core/inductive:cic-notations}}
\sphinxAtStartPar
\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\).

\sphinxAtStartPar
The case of inductive types 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/core/inductive: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/core/inductive: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}

\sphinxAtStartPar
The case of Inductive definitions of sort \(\Prop\) is a bit more
complicated, because of our interpretation of this sort. The only
harmless allowed eliminations, are the ones when predicate \(P\)
is also of sort \(\Prop\) or is of the morally smaller sort
\(\SProp\).
\begin{description}
\phantomsection\label{\detokenize{language/core/inductive:inference-Prop}}\item[{Prop}] \leavevmode \begin{equation*}
\begin{split}\frac{%
s ∈ \{\SProp,\Prop\}%
}{%
[I:\Prop|I→s]%
}\end{split}
\end{equation*}\end{description}

\sphinxAtStartPar
\(\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}

\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}{|} \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}

\sphinxAtStartPar
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}

\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}{|} \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}{SProp}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{or} \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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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\sphinxhyphen{}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\sphinxhyphen{}computational one, it just corresponds to proving a logical property
of a computational object.

\sphinxAtStartPar
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\sphinxhyphen{}irrelevance property which is sometimes a useful axiom:

\begin{sphinxadmonition}{note}{Example}

\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}

\sphinxAtStartPar
The elimination of an inductive type of sort \(\Prop\) on a predicate
\(P\) of type \(I→ \Type\) leads to a paradox when applied to impredicative
inductive definition like the second\sphinxhyphen{}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/core/inductive:empty-and-singleton-elimination}}
\sphinxAtStartPar
\sphinxstylestrong{Empty and singleton elimination.} There are special inductive definitions in
\(\Prop\) for which more eliminations are allowed.
\begin{description}
\phantomsection\label{\detokenize{language/core/inductive:inference-Prop-extended}}\item[{Prop\sphinxhyphen{}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}

\sphinxAtStartPar
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\sphinxhyphen{}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}

\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{k+kn}{Arguments} \PYG{n}{eq\PYGZus{}rec} \PYG{o}{[}\PYG{n}{A}\PYG{o}{]}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{function\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}

\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}

\sphinxAtStartPar
An empty definition has no constructors, in that case also,
elimination on any sort is allowed.

\phantomsection\label{\detokenize{language/core/inductive:eliminaton-for-sprop}}
\sphinxAtStartPar
Inductive types in \(\SProp\) must have no constructors (i.e. be
empty) to be eliminated to produce relevant values.

\sphinxAtStartPar
Note that thanks to proof irrelevance elimination functions can be
produced for other types, for instance the elimination for a unit type
is the identity.

\phantomsection\label{\detokenize{language/core/inductive:type-of-branches}}
\sphinxAtStartPar
\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 \(s\) is the number of
arguments.

\sphinxAtStartPar
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~q_1\ldots q_r\ t_1 \ldots t_s)\}^P &\equiv (P~t_1\ldots ~t_s~c) \\
\{c:∀ x:T,~C\}^P &\equiv ∀ x:T,~\{(c~x):C\}^P
\end{array}\end{split}
\end{equation*}
\sphinxAtStartPar
We write \(\{c\}^P\) for \(\{c:C\}^P\) with \(C\) the type of \(c\).

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The following term in concrete syntax:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
match t as l return P\PYGZsq{} with
| nil \PYGZus{} =\PYGZgt{} t1
| cons \PYGZus{} hd tl =\PYGZgt{} t2
end
\end{sphinxVerbatim}

\sphinxAtStartPar
can be represented in abstract syntax as
\begin{equation*}
\begin{split}\case(t,P,f_1 | f_2 )\end{split}
\end{equation*}
\sphinxAtStartPar
where
\begin{eqnarray*}
  P & = & λ l.~P^\prime\\
  f_1 & = & t_1\\
  f_2 & = & λ (hd:\nat).~λ (tl:\List~\nat).~t_2
\end{eqnarray*}
\sphinxAtStartPar
According to the definition:
\begin{equation*}
\begin{split}\{(\Nil~\nat)\}^P ≡ \{(\Nil~\nat) : (\List~\nat)\}^P ≡ (P~(\Nil~\nat))\end{split}
\end{equation*}\begin{equation*}
\begin{split}\begin{array}{rl}
\{(\cons~\nat)\}^P & ≡\{(\cons~\nat) : (\nat→\List~\nat→\List~\nat)\}^P \\
& ≡∀ n:\nat,~\{(\cons~\nat~n) : (\List~\nat→\List~\nat)\}^P \\
& ≡∀ n:\nat,~∀ l:\List~\nat,~\{(\cons~\nat~n~l) : (\List~\nat)\}^P \\
& ≡∀ n:\nat,~∀ l:\List~\nat,~(P~(\cons~\nat~n~l)).
\end{array}\end{split}
\end{equation*}
\sphinxAtStartPar
Given some \(P\) then \(\{(\Nil~\nat)\}^P\) represents the expected type of \(f_1\),
and \(\{(\cons~\nat)\}^P\) represents the expected type of \(f_2\).
\end{sphinxadmonition}
\phantomsection\label{\detokenize{language/core/inductive:typing-rule}}
\sphinxAtStartPar
\sphinxstylestrong{Typing rule.}
Our very general destructor for inductive definition enjoys the
following typing rule
\begin{description}
\phantomsection\label{\detokenize{language/core/inductive: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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
Below is a typing rule for the term shown in the previous example:
\begin{description}
\phantomsection\label{\detokenize{language/core/inductive: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 : \{(\Nil ~\nat)\}^P \\%
\hspace{3em}%
  E[Γ] ⊢ f_2 : \{(\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/core/inductive:definition-of-reduction}}
\sphinxAtStartPar
\sphinxstylestrong{Definition of ι\sphinxhyphen{}reduction.}
We still have to define the ι\sphinxhyphen{}reduction in the general case.

\sphinxAtStartPar
An ι\sphinxhyphen{}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*}
\sphinxAtStartPar
with \(c_{p_i}\) the \(i\)\sphinxhyphen{}th constructor of the inductive type \(I\) with \(r\)
parameters.

\sphinxAtStartPar
The ι\sphinxhyphen{}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_l ) \triangleright_ι (f_i~a_1 … a_m )\end{split}
\end{equation*}

\paragraph{Fixpoint definitions}
\label{\detokenize{language/core/inductive:fixpoint-definitions}}\label{\detokenize{language/core/inductive:id9}}
\sphinxAtStartPar
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*}
\sphinxAtStartPar
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*}
\sphinxAtStartPar
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*}
\sphinxAtStartPar
with \(t_i'\) (resp. \(A_i'\)) representing the term \(t_i\) abstracted (resp.
generalized) with respect to the bindings in the context \(Γ_i\), namely
\(t_i'=λ Γ_i . t_i\) and \(A_i'=∀ Γ_i , A_i\).


\subparagraph{Typing rule}
\label{\detokenize{language/core/inductive:id10}}
\sphinxAtStartPar
The typing rule is the expected one for a fixpoint.
\begin{description}
\phantomsection\label{\detokenize{language/core/inductive: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}

\sphinxAtStartPar
Any fixpoint definition cannot be accepted because non\sphinxhyphen{}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~\nO)→(∀ n:\nat,~(P~n)→(P~(\nS~n)))→ ∀ n:\nat,~(P~n)\end{split}
\end{equation*}
\sphinxAtStartPar
can be represented by the term:
\begin{equation*}
\begin{split}\begin{array}{l}
λ P:\nat→\Prop.~λ f:(P~\nO).~λ g:(∀ n:\nat,~(P~n)→(P~(\nS~n))).\\
\Fix~h\{h:∀ n:\nat,~(P~n):=λ n:\nat.~\case(n,P,f | λp:\nat.~(g~p~(h~p)))\}
\end{array}\end{split}
\end{equation*}
\sphinxAtStartPar
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 {[}\hyperlink{cite.zebibliography:id22}{Gimenez94}{]}. The first stage is to precise on which
argument the fixpoint will be decreasing. The type of this argument
should be an inductive type. For doing this, the syntax of
fixpoints is extended and becomes
\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*}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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\)\sphinxhyphen{}th argument should be
syntactically recognized as structurally smaller than \(y_{k_i}\).

\sphinxAtStartPar
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_m :T_m,~(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.

\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
\((t~u)\) and \(λ x:U .~t\) when \(t\) is structurally smaller than \(y\).

\item {} 
\sphinxAtStartPar
\(\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
type \(I_p\) part of the inductive definition 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_m :B_m ,~(I_p~p_1 … p_r~t_1 … t_s )\)
and can consequently be written \(λ y_1 :B_1' .~… λ y_m :B_m'.~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}

\sphinxAtStartPar
The following definitions are correct, we enter them using the {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}
command and show the internal representation.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
\PYG{o}{|} \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}{guarded} \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{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
      \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
      \PYG{o}{|} \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}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    
    \PYG{k+kn}{Arguments} \PYG{n}{plus} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}

\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{n}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
\PYG{o}{|} \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}{guarded} \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{n}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
      \PYG{o}{|} \PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
      \PYG{o}{|} \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{n}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    
    \PYG{k+kn}{Arguments} \PYG{n}{lgth} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}

\PYG{k+kn}{Fixpoint} \PYG{n}{sizet} \PYG{o}{(}\PYG{n}{t}\PYG{o}{:}\PYG{n}{tree}\PYG{o}{)} \PYG{o}{:} \PYG{n}{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{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{emptyf} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
\PYG{o}{|} \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}{guarded} \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{n}{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{n}{nat} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
      \PYG{o}{|} \PYG{n}{emptyf} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
      \PYG{o}{|} \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{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subparagraph{Reduction rule}
\label{\detokenize{language/core/inductive:reduction-rule}}\label{\detokenize{language/core/inductive:id12}}
\sphinxAtStartPar
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*}
\sphinxAtStartPar
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:
\begin{eqnarray*}
\plus~(\nS~(\nS~\nO))~(\nS~\nO)~& \trii & \nS~(\plus~(\nS~\nO)~(\nS~\nO))\\
                                & \trii & \nS~(\nS~(\plus~\nO~(\nS~\nO)))\\
                                & \trii & \nS~(\nS~(\nS~\nO))\\
\end{eqnarray*}\phantomsection\label{\detokenize{language/core/inductive:mutual-induction}}
\sphinxAtStartPar
\sphinxstylestrong{Mutual induction}

\sphinxAtStartPar
The principles of mutual induction can be automatically generated
using the Scheme command described in Section {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:proofschemes-induction-principles}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Scheme}}}}.


\subsection{Co\sphinxhyphen{}inductive types and co\sphinxhyphen{}recursive functions}
\label{\detokenize{language/core/coinductive:co-inductive-types-and-co-recursive-functions}}\label{\detokenize{language/core/coinductive::doc}}

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

\sphinxAtStartPar
More information on co\sphinxhyphen{}inductive definitions can be found in
{[}\hyperlink{cite.zebibliography:id25}{Gimenez95}, \hyperlink{cite.zebibliography:id23}{Gimenez98}, \hyperlink{cite.zebibliography:id24}{GimenezCasteran05}{]}.
\index{CoInductive (command)@\spxentry{CoInductive}\spxextra{command}}

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

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}},
{\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template)}}}}}, {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative)}}}}},
{\hyperref[\detokenize{language/core/variants:coq:attr.private(matching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{private(matching)}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(universes)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(universes)}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(positivity)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bypass\_check(positivity)}}}}}, and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:attr.using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{using}}}}} attributes.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The type of infinite sequences of natural numbers, usually called streams,
is an example of a co\sphinxhyphen{}inductive type.

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

\sphinxAtStartPar
The usual destructors on streams \sphinxcode{\sphinxupquote{\DUrole{name}{hd}\DUrole{operator}{:}\DUrole{name}{Stream}\DUrole{operator}{\sphinxhyphen{}>}\DUrole{name}{nat}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{tl}\DUrole{operator}{:}\DUrole{name}{Str}\DUrole{operator}{\sphinxhyphen{}>}\DUrole{name}{Str}}}
can be defined as follows:

\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}

\sphinxAtStartPar
Definitions of co\sphinxhyphen{}inductive predicates and blocks of mutually
co\sphinxhyphen{}inductive definitions are also allowed.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The extensional equality on streams is an example of a co\sphinxhyphen{}inductive type:

\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}

\sphinxAtStartPar
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/core/coinductive:cofixpoint}]{\sphinxcrossref{\DUrole{std,std-ref}{Top\sphinxhyphen{}level definitions of co\sphinxhyphen{}recursive functions}}}}.
\end{sphinxadmonition}


\paragraph{Caveat}
\label{\detokenize{language/core/coinductive:caveat}}
\sphinxAtStartPar
The ability to define co\sphinxhyphen{}inductive types by constructors, hereafter called
\sphinxstyleemphasis{positive co\sphinxhyphen{}inductive types}, is known to break subject reduction. The story is
a bit long: this is due to dependent pattern\sphinxhyphen{}matching which implies
propositional η\sphinxhyphen{}equality, which itself would require full η\sphinxhyphen{}conversion for
subject reduction to hold, but full η\sphinxhyphen{}conversion is not acceptable as it would
make type checking undecidable.

\sphinxAtStartPar
Since the introduction of primitive records in Coq 8.5, an alternative
presentation is available, called \sphinxstyleemphasis{negative co\sphinxhyphen{}inductive types}. This consists
in defining a co\sphinxhyphen{}inductive type as a primitive record type through its
projections. Such a technique is akin to the \sphinxstyleemphasis{co\sphinxhyphen{}pattern} style that can be
found in e.g. Agda, and preserves subject reduction.

\sphinxAtStartPar
The above example can be rewritten in the following way.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Primitive} \PYG{k+kn}{Projections}\PYG{o}{.}
\PYG{k+kn}{CoInductive} \PYG{n}{Stream} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{Seq} \PYG{o}{\PYGZob{}} \PYG{n}{hd} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{;} \PYG{n}{tl} \PYG{o}{:} \PYG{n}{Stream} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{Stream} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{hd} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tl} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{CoInductive} \PYG{n}{EqSt} \PYG{o}{(}\PYG{n}{s1} \PYG{n}{s2}\PYG{o}{:} \PYG{n}{Stream}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{eqst} \PYG{o}{\PYGZob{}}
  \PYG{n}{eqst\PYGZus{}hd} \PYG{o}{:} \PYG{n}{hd} \PYG{n}{s1} \PYG{o}{=} \PYG{n}{hd} \PYG{n}{s2}\PYG{o}{;}
  \PYG{n}{eqst\PYGZus{}tl} \PYG{o}{:} \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}{;}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{EqSt} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{eqst\PYGZus{}hd} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{eqst\PYGZus{}tl} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
Some properties that hold over positive streams are lost when going to the
negative presentation, typically when they imply equality over streams.
For instance, propositional η\sphinxhyphen{}equality is lost when going to the negative
presentation. It is nonetheless logically consistent to recover it through an
axiom.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{Stream\PYGZus{}eta} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{s}\PYG{o}{:} \PYG{n}{Stream}\PYG{o}{,} \PYG{n}{s} \PYG{o}{=} \PYG{n}{Seq} \PYG{o}{(}\PYG{n}{hd} \PYG{n}{s}\PYG{o}{)} \PYG{o}{(}\PYG{n}{tl} \PYG{n}{s}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Stream\PYGZus{}eta} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

\sphinxAtStartPar
More generally, as in the case of positive coinductive types, it is consistent
to further identify extensional equality of coinductive types with propositional
equality:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{Stream\PYGZus{}ext} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{s1} \PYG{n}{s2}\PYG{o}{:} \PYG{n}{Stream}\PYG{o}{)}\PYG{o}{,} \PYG{n}{EqSt} \PYG{n}{s1} \PYG{n}{s2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{s1} \PYG{o}{=} \PYG{n}{s2}\PYG{o}{.}
    \PYG{n}{Stream\PYGZus{}ext} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

\sphinxAtStartPar
As of Coq 8.9, it is now advised to use negative co\sphinxhyphen{}inductive types rather than
their positive counterparts.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{language/core/records:primitive-projections}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Projections}}}} for more information about negative
records and primitive projections.



\index{cofix@\spxentry{cofix}}\ignorespaces 

\subsubsection{Co\sphinxhyphen{}recursive functions: cofix}
\label{\detokenize{language/core/coinductive:co-recursive-functions-cofix}}\label{\detokenize{language/core/coinductive:index-0}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/coinductive:grammar-token-term_cofix}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/coinductive:grammar-token-term_cofix}]{\sphinxcrossref{\DUrole{hole}{term\_cofix}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let cofix {\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_body}]{\sphinxcrossref{\DUrole{hole}{cofix\_body}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{cofix {\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_body}]{\sphinxcrossref{\DUrole{hole}{cofix\_body}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_body}]{\sphinxcrossref{\DUrole{hole}{cofix\_body}}}}}\DUrole{notation-sup}{+}} for {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/coinductive:grammar-token-cofix_body}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_body}]{\sphinxcrossref{\DUrole{hole}{cofix\_body}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The expression
"\sphinxcode{\sphinxupquote{\DUrole{notation}{cofix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{1}}$}}}} with … with {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{n}}$}}}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder$_{\text{n}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{n}}$}}}} for {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}}"
denotes the \(i\)\sphinxhyphen{}th component of a block of terms defined by a mutual guarded
co\sphinxhyphen{}recursion. It is the local counterpart of the {\hyperref[\detokenize{language/core/coinductive:coq:cmd.CoFixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}} command. When
\(n=1\), the "\sphinxcode{\sphinxupquote{\DUrole{notation}{for {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}}" clause is omitted.


\subsubsection{Top\sphinxhyphen{}level definitions of co\sphinxhyphen{}recursive functions}
\label{\detokenize{language/core/coinductive:top-level-definitions-of-co-recursive-functions}}\label{\detokenize{language/core/coinductive:cofixpoint}}\index{CoFixpoint (command)@\spxentry{CoFixpoint}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/coinductive:coq:cmd.CoFixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{CoFixpoint~{\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_definition}]{\sphinxcrossref{\DUrole{hole}{cofix\_definition}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_definition}]{\sphinxcrossref{\DUrole{hole}{cofix\_definition}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/coinductive:grammar-token-cofix_definition}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_definition}]{\sphinxcrossref{\DUrole{hole}{cofix\_definition}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{:= {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}]{\sphinxcrossref{\DUrole{hole}{decl\_notations}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
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/core/coinductive:coinductive-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Co\sphinxhyphen{}inductive types}}}} for the definition of \sphinxcode{\sphinxupquote{\DUrole{name}{Stream}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{hd}}}
and \sphinxcode{\sphinxupquote{\DUrole{name}{tl}}}):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{CoFixpoint} \PYG{n}{from} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{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}

\sphinxAtStartPar
Unlike recursive definitions, there is no decreasing argument in a
co\sphinxhyphen{}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\sphinxhyphen{}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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{CoFixpoint} \PYG{n}{filter} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Stream} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Stream}
    \PYG{n}{p} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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)}
\PYG{l+s+s2}{     then \PYGZob{}| hd := hd s; tl := filter p (tl s) |\PYGZcb{}}
\PYG{l+s+s2}{     else filter p (tl s)}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The elimination of co\sphinxhyphen{}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{proofs/writing-proofs/equality:coq:cmd.Eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Eval}}}}}, which computes
the normal forms of a term:

\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{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Stream} \PYG{o}{:=} \PYG{o}{\PYGZob{}|} \PYG{n}{hd} \PYG{o}{:=} \PYG{n}{n}\PYG{o}{;} \PYG{n}{tl} \PYG{o}{:=} \PYG{n}{from} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{|\PYGZcb{}}\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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Stream} \PYG{o}{:=} \PYG{o}{\PYGZob{}|} \PYG{n}{hd} \PYG{o}{:=} \PYG{n}{n}\PYG{o}{;} \PYG{n}{tl} \PYG{o}{:=} \PYG{n}{from} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{|\PYGZcb{}}\PYG{o}{)} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{n}{Stream}
\end{sphinxVerbatim}

\sphinxAtStartPar
As in the {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} command, the \sphinxcode{\sphinxupquote{\DUrole{notation}{with}}} clause allows simultaneously
defining several mutual cofixpoints.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is omitted, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} is required and Coq enters proof mode.
This can be used to define a term incrementally, in particular by relying on the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic.
In this case, the proof should be terminated with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}} in order to define a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}}
for which the computational behavior is relevant.  See {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Entering and exiting proof mode}}}}.

\end{fulllineitems}\end{savenotes}



\subsection{Section mechanism}
\label{\detokenize{language/core/sections:section-mechanism}}\label{\detokenize{language/core/sections:id1}}\label{\detokenize{language/core/sections::doc}}
\sphinxAtStartPar
Sections are naming scopes that permit creating section\sphinxhyphen{}local declarations that can
be used by other declarations in the section.  Declarations made
with {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}}, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Hypothesis}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hypothesis}}}}}, {\hyperref[\detokenize{language/core/sections:coq:cmd.Context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Context}}}}},
{\hyperref[\detokenize{language/core/sections:coq:cmd.Let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let}}}}}, {\hyperref[\detokenize{language/core/sections:coq:cmd.Let-Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let Fixpoint}}}}} and
{\hyperref[\detokenize{language/core/sections:coq:cmd.Let-CoFixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let CoFixpoint}}}}} (or the plural variants of the first two) within sections
are local to the section.

\sphinxAtStartPar
In proofs done within the section, section\sphinxhyphen{}local declarations
are included in the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-local-context}]{\sphinxtermref{\DUrole{xref,std,std-term}{local context}}}} of the initial goal of the proof.
They are also accessible in definitions made with the {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} command.

\sphinxAtStartPar
Sections are opened by the {\hyperref[\detokenize{language/core/sections:coq:cmd.Section}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Section}}}}} command, and closed by {\hyperref[\detokenize{language/core/sections:coq:cmd.End}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{End}}}}}.
Sections can be nested.
When a section is closed, its local declarations are no longer available.
Global declarations that refer to them will be adjusted so they're still
usable outside the section as shown in this {\hyperref[\detokenize{language/core/sections:section-local-declarations}]{\sphinxcrossref{\DUrole{std,std-ref}{example}}}}.
\index{Section (command)@\spxentry{Section}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/sections:coq:cmd.Section}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Section~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Opens the section named {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.
Section names do not need to be unique.

\end{fulllineitems}\end{savenotes}

\index{End (command)@\spxentry{End}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/sections:coq:cmd.End}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{End~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Closes the section or module named {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.
See {\hyperref[\detokenize{language/core/modules:terminating-module}]{\sphinxcrossref{\DUrole{std,std-ref}{Terminating an interactive module or module type definition}}}}
for a description of its use with modules.

\sphinxAtStartPar
After closing the
section, the local declarations (variables and local definitions, see {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}}) are
\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.
\index{There is nothing to end (error)@\spxentry{There is nothing to end}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/sections:coq:exn.There-is-nothing-to-end}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{There~is~nothing~to~end.}}}}
\end{fulllineitems}\end{savenotes}

\index{Last block to end has name ‘ident’ (error)@\spxentry{Last block to end has name ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/sections:coq:exn.Last-block-to-end-has-name-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Last~block~to~end~has~name~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Most commands, such as the {\hyperref[\detokenize{proofs/automatic-tactics/auto:creating-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Hint}}}} commands,
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} and option management commands that
appear inside a section are canceled when the section is closed.
\end{sphinxadmonition}
\index{Let (command)@\spxentry{Let}\spxextra{command}}\index{Let Fixpoint (command)@\spxentry{Let Fixpoint}\spxextra{command}}\index{Let CoFixpoint (command)@\spxentry{Let CoFixpoint}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/sections:coq:cmd.Let}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Let~{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~{\hyperref[\detokenize{language/core/definitions:grammar-token-def_body}]{\sphinxcrossref{\DUrole{hole}{def\_body}}}}}}}}\phantomsection\label{\detokenize{language/core/sections:coq:cmd.Let-Fixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Let~Fixpoint~{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_definition}]{\sphinxcrossref{\DUrole{hole}{fix\_definition}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_definition}]{\sphinxcrossref{\DUrole{hole}{fix\_definition}}}}}\DUrole{notation-sup}{*}}}}}}\phantomsection\label{\detokenize{language/core/sections:coq:cmd.Let-CoFixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Let~CoFixpoint~{\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_definition}]{\sphinxcrossref{\DUrole{hole}{cofix\_definition}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/coinductive:grammar-token-cofix_definition}]{\sphinxcrossref{\DUrole{hole}{cofix\_definition}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
These are similar to {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}, {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} and {\hyperref[\detokenize{language/core/coinductive:coq:cmd.CoFixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}}, except that
the declared {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} is local to the current section.
When the section is closed, all persistent
definitions and theorems within it that depend on the constant
will be wrapped with a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/definitions:grammar-token-term_let}]{\sphinxcrossref{\DUrole{hole}{term\_let}}}}}}} with the same declaration.

\sphinxAtStartPar
As for {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}, {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} and {\hyperref[\detokenize{language/core/coinductive:coq:cmd.CoFixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}},
if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is omitted, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} is required and Coq enters proof mode.
This can be used to define a term incrementally, in particular by relying on the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic.
In this case, the proof should be terminated with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}} in order to define a constant
for which the computational behavior is relevant.  See {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Entering and exiting proof mode}}}}.

\end{fulllineitems}\end{savenotes}

\index{Context (command)@\spxentry{Context}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/sections:coq:cmd.Context}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Context~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Declare variables in the context of the current section, like {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}},
but also allowing implicit variables, {\hyperref[\detokenize{language/extensions/implicit-arguments:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit generalization}}}}, and
let\sphinxhyphen{}binders.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Context} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Context} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Context} \PYG{o}{(}\PYG{n}{b\PYGZsq{}} \PYG{o}{:=} \PYG{n}{b}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\end{fulllineitems}\end{savenotes}



\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
Section {\hyperref[\detokenize{language/core/assumptions:binders}]{\sphinxcrossref{\DUrole{std,std-ref}{Binders}}}}. Section {\hyperref[\detokenize{addendum/type-classes:contexts}]{\sphinxcrossref{\DUrole{std,std-ref}{Sections and contexts}}}} in chapter {\hyperref[\detokenize{addendum/type-classes:typeclasses}]{\sphinxcrossref{\DUrole{std,std-ref}{Typeclasses}}}}.


\phantomsection\label{\detokenize{language/core/sections:section-local-declarations}}
\begin{sphinxadmonition}{note}{Example: Section\sphinxhyphen{}local declarations}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{s1}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{y} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

\sphinxAtStartPar
The command {\hyperref[\detokenize{language/core/sections:coq:cmd.Let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let}}}}} introduces section\sphinxhyphen{}wide {\hyperref[\detokenize{language/core/definitions:let-in}]{\sphinxcrossref{\DUrole{std,std-ref}{Let\sphinxhyphen{}in definitions}}}}. These definitions
won't persist when the section is closed, and all persistent definitions which
depend on \sphinxcode{\sphinxupquote{y'}} will be prefixed with \sphinxcode{\sphinxupquote{let y' := y in}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Let} \PYG{n}{y\PYGZsq{}} \PYG{o}{:=} \PYG{n}{y}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{x\PYGZsq{}} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{x\PYGZsq{}\PYGZsq{}} \PYG{o}{:=} \PYG{n}{x\PYGZsq{}} \PYG{o}{+} \PYG{n}{y\PYGZsq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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{n}{nat}

\PYG{k+kn}{Print} \PYG{n}{x\PYGZsq{}\PYGZsq{}}\PYG{o}{.}
    \PYG{n}{x\PYGZsq{}\PYGZsq{}} \PYG{o}{=} \PYG{n}{x\PYGZsq{}} \PYG{o}{+} \PYG{n}{y\PYGZsq{}}
         \PYG{o}{:} \PYG{n}{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{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{x}
         \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    
    \PYG{k+kn}{Arguments} \PYG{n}{x\PYGZsq{}} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}

\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{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    
    \PYG{k+kn}{Arguments} \PYG{n}{x\PYGZsq{}\PYGZsq{}} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}
\end{sphinxVerbatim}

\sphinxAtStartPar
Notice the difference between the value of \sphinxcode{\sphinxupquote{\DUrole{name}{x'}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{x''}}} inside section
\sphinxcode{\sphinxupquote{\DUrole{name}{s1}}} and outside.
\end{sphinxadmonition}


\subsection{The Module System}
\label{\detokenize{language/core/modules:the-module-system}}\label{\detokenize{language/core/modules:themodulesystem}}\label{\detokenize{language/core/modules::doc}}
\sphinxAtStartPar
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.


\subsubsection{Modules and module types}
\label{\detokenize{language/core/modules:modules-and-module-types}}
\sphinxAtStartPar
\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.

\sphinxAtStartPar
\sphinxstylestrong{Structure element.} A structure element is denoted by \(e\) and
is either a definition of a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}}, an assumption, a definition of
an inductive, a definition of a module, an alias of a module or a module
type abbreviation.

\sphinxAtStartPar
\sphinxstylestrong{Structure expression.} A structure expression is denoted by \(S\) and can be:
\begin{itemize}
\item {} 
\sphinxAtStartPar
an access path \(p\)

\item {} 
\sphinxAtStartPar
a plain structure \(\Struct~e ; … ; e~\End\)

\item {} 
\sphinxAtStartPar
a functor \(\Functor(X:S)~S′\), where \(X\) is a module variable, \(S\) and \(S′\) are
structure expressions

\item {} 
\sphinxAtStartPar
an application \(S~p\), where \(S\) is a structure expression and \(p\) an
access path

\item {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
\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.

\sphinxAtStartPar
\sphinxstylestrong{Module alias.} A module alias is written \(\ModA{X}{p}\)
and consists of a module variable \(X\) and a module path
\(p\).

\sphinxAtStartPar
\sphinxstylestrong{Module type abbreviation.}
A module type abbreviation is written \(\ModType{Y}{S}\),
where \(Y\) is an identifier and \(S\) is any structure
expression .


\subsubsection{Using modules}
\label{\detokenize{language/core/modules:using-modules}}
\sphinxAtStartPar
The module system provides a way of packaging related elements
together, as well as a means of massive abstraction.
\index{Module (command)@\spxentry{Module}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:cmd.Module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{Import}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Export}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-of_module_type}]{\sphinxcrossref{\DUrole{hole}{of\_module\_type}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:=~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_inl}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_inl}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{<+}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-module_binder}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{Import}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Export}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-module_type_inl}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{! {\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-functor_app_annot}]{\sphinxcrossref{\DUrole{hole}{functor\_app\_annot}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-functor_app_annot}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-functor_app_annot}]{\sphinxcrossref{\DUrole{hole}{functor\_app\_annot}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} inline at level {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} no inline {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-module_type}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}} {\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_atom}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_atom}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}} with {\hyperref[\detokenize{language/core/modules:grammar-token-with_declaration}]{\sphinxcrossref{\DUrole{hole}{with\_declaration}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-with_declaration}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-with_declaration}]{\sphinxcrossref{\DUrole{hole}{with\_declaration}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Definition {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_decl}]{\sphinxcrossref{\DUrole{hole}{univ\_decl}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Module {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} := {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-module_expr_atom}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_atom}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_atom}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_atom}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_atom}}}}}\DUrole{notation-sup}{+}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-of_module_type}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-of_module_type}]{\sphinxcrossref{\DUrole{hole}{of\_module\_type}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{: {\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{<: {\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-module_expr_inl}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_inl}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_inl}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{! \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_atom}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_atom}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_atom}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_atom}}}}}\DUrole{notation-sup}{+}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-functor_app_annot}]{\sphinxcrossref{\DUrole{hole}{functor\_app\_annot}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Defines a module named {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.  See the examples {\hyperref[\detokenize{language/core/modules:module-examples}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{Import}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{Export}}} flags specify whether the module should be automatically
imported or exported.

\sphinxAtStartPar
Specifying \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}\DUrole{notation-sup}{*}}}}} starts a functor with
parameters given by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}}}s.  (A \sphinxstyleemphasis{functor} is a function
from modules to modules.)

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-of_module_type}]{\sphinxcrossref{\DUrole{hole}{of\_module\_type}}}}}}} specifies the module type.  \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{<: {\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}\DUrole{notation-sup}{+}}}}}
starts a module that satisfies each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{:= \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_inl}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_inl}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{<+}}}}} specifies the body of a module or functor
definition.  If it's not specified, then the module is defined \sphinxstyleemphasis{interactively},
meaning that the module is defined as a series of commands terminated with {\hyperref[\detokenize{language/core/sections:coq:cmd.End}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{End}}}}}
instead of in a single {\hyperref[\detokenize{language/core/modules:coq:cmd.Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module}}}}} command.
Interactively defining the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_inl}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_inl}}}}}}}s in a series of
{\hyperref[\detokenize{language/core/modules:coq:cmd.Include}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Include}}}}} commands is equivalent to giving them all in a single
non\sphinxhyphen{}interactive {\hyperref[\detokenize{language/core/modules:coq:cmd.Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module}}}}} command.

\sphinxAtStartPar
The ! prefix indicates that any assumption command (such as {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}}) with an \sphinxcode{\sphinxupquote{\DUrole{notation}{Inline}}} clause
in the type of the functor arguments will be ignored.

\end{fulllineitems}\end{savenotes}

\index{Module Type (command)@\spxentry{Module Type}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:cmd.Module-Type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~Type~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{<:~{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:=~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{<+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Defines a module type named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.  See the example {\hyperref[\detokenize{language/core/modules:example-def-simple-module-type}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\sphinxAtStartPar
Specifying \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}\DUrole{notation-sup}{*}}}}} starts a functor type with
parameters given by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}}}s.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{:= \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{<+}}}}} specifies the body of a module or functor type
definition.  If it's not specified, then the module type is defined \sphinxstyleemphasis{interactively},
meaning that the module type is defined as a series of commands terminated with {\hyperref[\detokenize{language/core/sections:coq:cmd.End}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{End}}}}}
instead of in a single {\hyperref[\detokenize{language/core/modules:coq:cmd.Module-Type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module Type}}}}} command.
Interactively defining the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}}}s in a series of
{\hyperref[\detokenize{language/core/modules:coq:cmd.Include}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Include}}}}} commands is equivalent to giving them all in a single
non\sphinxhyphen{}interactive {\hyperref[\detokenize{language/core/modules:coq:cmd.Module-Type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module Type}}}}} command.

\end{fulllineitems}\end{savenotes}

\phantomsection\label{\detokenize{language/core/modules:terminating-module}}
\sphinxAtStartPar
\sphinxstylestrong{Terminating an interactive module or module type definition}

\sphinxAtStartPar
Interactive modules are terminated with the {\hyperref[\detokenize{language/core/sections:coq:cmd.End}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{End}}}}} command, which
is also used to terminate {\hyperref[\detokenize{language/core/sections:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Sections}}}}.
\sphinxcode{\sphinxupquote{\DUrole{notation}{End {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} closes the interactive module or module type {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.
If the module type was given, the command verifies that the content of the module
matches the module type.  If the module is not a
functor, its components ({\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}}, inductive types, submodules etc.)
are now available through the dot notation.
\index{No such label ‘ident’ (error)@\spxentry{No such label ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:exn.No-such-label-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~label~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{Signature components for label ‘ident’ do not match (error)@\spxentry{Signature components for label ‘ident’ do not match}\spxextra{error}}

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

\index{The field ‘ident’ is missing in ‘qualid’ (error)@\spxentry{The field ‘ident’ is missing in ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:exn.The-field-_u2018ident_u2019-is-missing-in-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~field~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~missing~in~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
Interactive modules and module types can be nested.

\item {} 
\sphinxAtStartPar
Interactive modules and module types can't be defined inside of {\hyperref[\detokenize{language/core/sections:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{sections}}}}.
Sections can be defined inside of interactive modules and module types.

\item {} 
\sphinxAtStartPar
Hints and notations (the {\hyperref[\detokenize{proofs/automatic-tactics/auto:creating-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Hint}}}} and {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}}
commands) can also appear inside interactive
modules and module types. Note that with module definitions like:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Module {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}}

\sphinxAtStartPar
or

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Module {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}.}}} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{Include {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{End {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}.}}}

\sphinxAtStartPar
hints and the like valid for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} are the ones defined in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}}
rather then those defined in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} (or the module body).

\item {} 
\sphinxAtStartPar
Within an interactive module type definition, the {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Parameter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Parameter}}}}} command declares a
{\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} instead of definining a new axiom (which it does when not in a module type definition).

\item {} 
\sphinxAtStartPar
Assumptions such as {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}} that include the \sphinxcode{\sphinxupquote{\DUrole{notation}{Inline}}} clause will be automatically
expanded when the functor is applied, except when the function application is prefixed by \sphinxcode{\sphinxupquote{!}}.

\end{enumerate}
\end{sphinxadmonition}
\index{Include (command)@\spxentry{Include}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:cmd.Include}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Include~{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{<+~{\hyperref[\detokenize{language/core/modules:grammar-token-module_expr_inl}]{\sphinxcrossref{\DUrole{hole}{module\_expr\_inl}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
Includes the content of module(s) in the current
interactive module. Here \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}}} can be a module expression or a module
type expression. If it is a high\sphinxhyphen{}order module or module type
expression then the system tries to instantiate \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}}} with the current
interactive module.

\sphinxAtStartPar
Including multiple modules is a single {\hyperref[\detokenize{language/core/modules:coq:cmd.Include}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Include}}}}} is equivalent to including each module
in a separate {\hyperref[\detokenize{language/core/modules:coq:cmd.Include}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Include}}}}} command.

\end{fulllineitems}\end{savenotes}

\index{Include Type (command)@\spxentry{Include Type}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:cmd.Include-Type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Include~Type~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{<+}}}}}}~
\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.3: }Use {\hyperref[\detokenize{language/core/modules:coq:cmd.Include}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Include}}}}} instead.

\end{fulllineitems}\end{savenotes}

\index{Declare Module (command)@\spxentry{Declare Module}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:cmd.Declare-Module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Module~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{Import}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Export}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\DUrole{hole}{module\_type\_inl}}}}}}}}
\sphinxAtStartPar
Declares a module {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} of type {\hyperref[\detokenize{language/core/modules:grammar-token-module_type_inl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{module\_type\_inl}}}}}.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\DUrole{hole}{module\_binder}}}}}}}s are specified, declares a functor with parameters given by the list of
{\hyperref[\detokenize{language/core/modules:grammar-token-module_binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{module\_binder}}}}}s.

\end{fulllineitems}\end{savenotes}

\index{Import (command)@\spxentry{Import}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:cmd.Import}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Import~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-filtered_import}]{\sphinxcrossref{\DUrole{hole}{filtered\_import}}}}}\DUrole{notation-sup}{+}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-filtered_import}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-filtered_import}]{\sphinxcrossref{\DUrole{hole}{filtered\_import}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{( .. )}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
If {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{Mod}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{T}\PYG{o}{:=}\PYG{n}{nat}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{T}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{Mod}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{Mod}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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}

\sphinxAtStartPar
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}}}}).

\sphinxAtStartPar
Declarations made with the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute are never imported by the {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}}
command. Such declarations are only accessible through their fully
qualified name.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Module} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{Local} \PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{n}{nat}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Import} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{B}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{6}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{9}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Check} \PYG{n}{B}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}       \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\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}

\sphinxAtStartPar
Appending a module name with a parenthesized list of names will
make only those names available with short names, not other names
defined in the module nor will it activate other features.

\sphinxAtStartPar
The names to import may be {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}}, inductive types and
constructors, and notation aliases (for instance, Ltac definitions
cannot be selectively imported). If they are from an inner module
to the one being imported, they must be prefixed by the inner path.

\sphinxAtStartPar
The name of an inductive type may also be followed by \sphinxcode{\sphinxupquote{(..)}} to
import it, its constructors and its eliminators if they exist. For
this purpose "eliminator" means a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} in the same module whose
name is the inductive type's name suffixed by one of \sphinxcode{\sphinxupquote{\_sind}},
\sphinxcode{\sphinxupquote{\_ind}}, \sphinxcode{\sphinxupquote{\_rec}} or \sphinxcode{\sphinxupquote{\_rect}}.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Module} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{T} \PYG{o}{:=} \PYG{n}{C}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{U} \PYG{o}{:=} \PYG{n}{nat}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{Z} \PYG{o}{:=} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Import} \PYG{n}{A}\PYG{o}{(}\PYG{n}{B}\PYG{o}{.}\PYG{n}{T}\PYG{o}{(}\PYG{o}{..}\PYG{o}{)}\PYG{o}{,} \PYG{n}{Z}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{B}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
    \PYG{n}{B}\PYG{o}{.}\PYG{n}{T}
         \PYG{o}{:} \PYG{k+kt}{Prop}

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

\PYG{k+kn}{Check} \PYG{n}{Z}\PYG{o}{.}
    \PYG{n}{Z}
         \PYG{o}{:} \PYG{k+kt}{Type}

\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{n}{B}\PYG{o}{.}\PYG{n}{U}\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}{U} \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}{Check} \PYG{n}{A}\PYG{o}{.}\PYG{n}{B}\PYG{o}{.}\PYG{n}{U}\PYG{o}{.}
    \PYG{n}{A}\PYG{o}{.}\PYG{n}{B}\PYG{o}{.}\PYG{n}{U}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{Export (command)@\spxentry{Export}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:cmd.Export}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Export~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-filtered_import}]{\sphinxcrossref{\DUrole{hole}{filtered\_import}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Similar to {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}}, except that when the module containing this command
is imported, the \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}} are imported as well.

\sphinxAtStartPar
The selective import syntax also works with Export.
\index{‘qualid’ is not a module (error)@\spxentry{‘qualid’ is not a module}\spxextra{error}}

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

\index{Trying to mask the absolute name ‘qualid’"! (warning)@\spxentry{Trying to mask the absolute name ‘qualid’"!}\spxextra{warning}}

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


\end{fulllineitems}\end{savenotes}

\index{Print Module (command)@\spxentry{Print Module}\spxextra{command}}

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

\end{fulllineitems}\end{savenotes}

\index{Print Module Type (command)@\spxentry{Print Module Type}\spxextra{command}}

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

\end{fulllineitems}\end{savenotes}

\index{Short Module Printing (flag)@\spxentry{Short Module Printing}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:flag.Short-Module-Printing}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Short~Module~Printing}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (off by default) disables the printing of the types of fields,
leaving only their names, for the commands {\hyperref[\detokenize{language/core/modules:coq:cmd.Print-Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Module}}}}} and
{\hyperref[\detokenize{language/core/modules:coq:cmd.Print-Module-Type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Module Type}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Examples}
\label{\detokenize{language/core/modules:examples}}\label{\detokenize{language/core/modules:module-examples}}
\begin{sphinxadmonition}{note}{Example: Defining a simple module interactively}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{M}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{n}{nat}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{x} \PYG{o}{:=} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{y} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{bool}

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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Defined}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{M}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Inside a module one can define {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}}, prove theorems and do anything
else that can be done in the toplevel. Components of a closed
module can be accessed using the dot notation:

\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{n}{nat}
\end{sphinxVerbatim}
\phantomsection\label{\detokenize{language/core/modules:example-def-simple-module-type}}
\begin{sphinxadmonition}{note}{Example: Defining a simple module type interactively}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{T} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{SIG}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{language/core/modules:example-filter-module}}
\begin{sphinxadmonition}{note}{Example: Creating a new module that omits some items from an existing module}

\sphinxAtStartPar
Since \sphinxcode{\sphinxupquote{\DUrole{notation}{SIG}}}, the type of the new module \sphinxcode{\sphinxupquote{\DUrole{notation}{N}}}, doesn't define \sphinxcode{\sphinxupquote{\DUrole{notation}{y}}} or
give the body of \sphinxcode{\sphinxupquote{\DUrole{notation}{x}}}, which are not included in \sphinxcode{\sphinxupquote{\DUrole{notation}{N}}}.

\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{n}{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{n}{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}
\end{sphinxadmonition}

\sphinxAtStartPar
The definition of \sphinxcode{\sphinxupquote{\DUrole{name}{N}}} using the module type expression \sphinxcode{\sphinxupquote{\DUrole{name}{SIG}}} with
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Definition} \DUrole{name}{T} \DUrole{operator}{:=} \DUrole{name}{nat}}} is equivalent to the following one:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG\PYGZsq{}}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{nat}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{SIG\PYGZsq{}}\PYG{o}{.}

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

\sphinxAtStartPar
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

\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}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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{n}{bool}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Example: Creating a functor (a module with parameters)}

\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{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{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{k+kn}{End} \PYG{n}{Two}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
and apply it to our modules and do some computations:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{Q} \PYG{o}{:=} \PYG{n}{Two} \PYG{n}{M} \PYG{n}{N}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: A module type with two sub\sphinxhyphen{}modules, sharing some fields}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG2}\PYG{o}{.}
  \PYG{n}{Declare} \PYG{k+kn}{Module} \PYG{n}{M1} \PYG{o}{:} \PYG{n}{SIG}\PYG{o}{.}
  \PYG{k+kn}{Module} \PYG{n}{M2} \PYG{o}{\PYGZlt{}}\PYG{o}{:} \PYG{n}{SIG}\PYG{o}{.}
    \PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{n}{M1}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
    \PYG{k+kn}{Parameter} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{.}
  \PYG{k+kn}{End} \PYG{n}{M2}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{SIG2}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{Mod} \PYG{o}{\PYGZlt{}}\PYG{o}{:} \PYG{n}{SIG2}\PYG{o}{.}
  \PYG{k+kn}{Module} \PYG{n}{M1}\PYG{o}{.}
    \PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{n}{nat}\PYG{o}{.}
    \PYG{k+kn}{Definition} \PYG{n}{x} \PYG{o}{:=} \PYG{l+m+mi}{1}\PYG{o}{.}
  \PYG{k+kn}{End} \PYG{n}{M1}\PYG{o}{.}
\PYG{k+kn}{Module} \PYG{n}{M2} \PYG{o}{:=} \PYG{n}{M}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{Mod}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

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


\subsubsection{Typing Modules}
\label{\detokenize{language/core/modules:typing-modules}}
\sphinxAtStartPar
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 {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} and inductive types now also
hold any other structure elements. Terms, apart from variables, {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} and
complex terms, also include access paths.

\sphinxAtStartPar
We also need additional typing judgments:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\(\WFT{E}{S}\), denoting that a structure \(S\) is well\sphinxhyphen{}formed,

\item {} 
\sphinxAtStartPar
\(\WTM{E}{p}{S}\), denoting that the module pointed by \(p\) has type \(S\) in
the global environment \(E\).

\item {} 
\sphinxAtStartPar
\(\WEV{E}{S}{\ovl{S}}\), denoting that a structure \(S\) is evaluated to a
structure \(\ovl{S}\) in weak head normal form.

\item {} 
\sphinxAtStartPar
\(\WS{E}{S_1}{S_2}\) , denoting that a structure \(S_1\) is a subtype of a
structure \(S_2\).

\item {} 
\sphinxAtStartPar
\(\WS{E}{e_1}{e_2}\) , denoting that a structure element \(e_1\) is more
precise than a structure element \(e_2\).

\end{itemize}

\sphinxAtStartPar
The rules for forming structures are the following:
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-WF-STR}}\item[{WF\sphinxhyphen{}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/core/modules:inference-WF-FUN}}\item[{WF\sphinxhyphen{}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}

\sphinxAtStartPar
Evaluation of structures to weak head normal form:
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-WEVAL-APP}}\item[{WEVAL\sphinxhyphen{}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}

\sphinxAtStartPar
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\sphinxhyphen{}reduced term \(t_i\) in \(p\).
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-WEVAL-WITH-MOD}}\item[{WEVAL\sphinxhyphen{}WITH\sphinxhyphen{}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/core/modules:inference-WEVAL-WITH-MOD-REC}}\item[{WEVAL\sphinxhyphen{}WITH\sphinxhyphen{}MOD\sphinxhyphen{}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/core/modules:inference-WEVAL-WITH-DEF}}\item[{WEVAL\sphinxhyphen{}WITH\sphinxhyphen{}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/core/modules:inference-WEVAL-WITH-DEF-REC}}\item[{WEVAL\sphinxhyphen{}WITH\sphinxhyphen{}DEF\sphinxhyphen{}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/core/modules:inference-WEVAL-PATH-MOD1}}\item[{WEVAL\sphinxhyphen{}PATH\sphinxhyphen{}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/core/modules:inference-WEVAL-PATH-MOD2}}\item[{WEVAL\sphinxhyphen{}PATH\sphinxhyphen{}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/core/modules:inference-WEVAL-PATH-ALIAS1}}\item[{WEVAL\sphinxhyphen{}PATH\sphinxhyphen{}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/core/modules:inference-WEVAL-PATH-ALIAS2}}\item[{WEVAL\sphinxhyphen{}PATH\sphinxhyphen{}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/core/modules:inference-WEVAL-PATH-TYPE1}}\item[{WEVAL\sphinxhyphen{}PATH\sphinxhyphen{}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/core/modules:inference-WEVAL-PATH-TYPE2}}\item[{WEVAL\sphinxhyphen{}PATH\sphinxhyphen{}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}

\sphinxAtStartPar
Rules for typing module:
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-MT-EVAL}}\item[{MT\sphinxhyphen{}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/core/modules:inference-MT-STR}}\item[{MT\sphinxhyphen{}STR}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ p : S%
}{%
E[] ⊢ p : S/p%
}\end{split}
\end{equation*}\end{description}

\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
\(\Def{}{c}{t}{T}/p = \Def{}{c}{t}{T}\)

\item {} 
\sphinxAtStartPar
\(\Assum{}{c}{U}/p = \Def{}{c}{p.c}{U}\)

\item {} 
\sphinxAtStartPar
\(\ModS{X}{S}/p = \ModA{X}{p.X}\)

\item {} 
\sphinxAtStartPar
\(\ModA{X}{p′}/p = \ModA{X}{p′}\)

\item {} 
\sphinxAtStartPar
\(\Ind{}{Γ_P}{Γ_C}{Γ_I}/p = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p}\)

\item {} 
\sphinxAtStartPar
\(\Indpstr{}{Γ_P}{Γ_C}{Γ_I}{p'}{p} = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'}\)

\end{itemize}

\item {} 
\sphinxAtStartPar
if \(S \lra \Functor(X:S′)~S″\) then \(S/p=S\)

\end{itemize}

\sphinxAtStartPar
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.

\sphinxAtStartPar
The module subtyping rules:
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-MSUB-STR}}\item[{MSUB\sphinxhyphen{}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/core/modules:inference-MSUB-FUN}}\item[{MSUB\sphinxhyphen{}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}

\sphinxAtStartPar
Structure element subtyping rules:
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-ASSUM-ASSUM}}\item[{ASSUM\sphinxhyphen{}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/core/modules:inference-DEF-ASSUM}}\item[{DEF\sphinxhyphen{}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/core/modules:inference-ASSUM-DEF}}\item[{ASSUM\sphinxhyphen{}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/core/modules:inference-DEF-DEF}}\item[{DEF\sphinxhyphen{}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/core/modules:inference-IND-IND}}\item[{IND\sphinxhyphen{}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/core/modules:inference-INDP-IND}}\item[{INDP\sphinxhyphen{}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/core/modules:inference-INDP-INDP}}\item[{INDP\sphinxhyphen{}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/core/modules:inference-MOD-MOD}}\item[{MOD\sphinxhyphen{}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/core/modules:inference-ALIAS-MOD}}\item[{ALIAS\sphinxhyphen{}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/core/modules:inference-MOD-ALIAS}}\item[{MOD\sphinxhyphen{}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/core/modules:inference-ALIAS-ALIAS}}\item[{ALIAS\sphinxhyphen{}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/core/modules:inference-MODTYPE-MODTYPE}}\item[{MODTYPE\sphinxhyphen{}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}

\sphinxAtStartPar
New environment formation rules
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-WF-MOD1}}\item[{WF\sphinxhyphen{}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/core/modules:inference-WF-MOD2}}\item[{WF\sphinxhyphen{}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; \ModImp{X}{S_1}{S_2}}{}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-WF-ALIAS}}\item[{WF\sphinxhyphen{}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/core/modules:inference-WF-MODTYPE}}\item[{WF\sphinxhyphen{}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/core/modules:inference-WF-IND}}\item[{WF\sphinxhyphen{}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}

\sphinxAtStartPar
Component access rules
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-ACC-TYPE1}}\item[{ACC\sphinxhyphen{}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/core/modules:inference-ACC-TYPE2}}\item[{ACC\sphinxhyphen{}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}

\sphinxAtStartPar
Notice that the following rule extends the delta rule defined in section {\hyperref[\detokenize{language/core/conversion:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}}
\begin{description}
\phantomsection\label{\detokenize{language/core/modules:inference-ACC-DELTA}}\item[{ACC\sphinxhyphen{}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}

\sphinxAtStartPar
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/core/modules:inference-ACC-IND1}}\item[{ACC\sphinxhyphen{}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/core/modules:inference-ACC-IND2}}\item[{ACC\sphinxhyphen{}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/core/modules:inference-ACC-INDP1}}\item[{ACC\sphinxhyphen{}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/core/modules:inference-ACC-INDP2}}\item[{ACC\sphinxhyphen{}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}


\subsubsection{Libraries and qualified names}
\label{\detokenize{language/core/modules:libraries-and-qualified-names}}

\paragraph{Names of libraries}
\label{\detokenize{language/core/modules:names-of-libraries}}\label{\detokenize{language/core/modules:id1}}
\sphinxAtStartPar
The theories developed in 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/core/modules:qualified-names}]{\sphinxcrossref{\DUrole{std,std-ref}{Qualified identifiers}}}}). For instance, the library file \sphinxcode{\sphinxupquote{Mult}} of the standard
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 Coq have the reserved root Coq but library
filenames based on other roots can be obtained by using Coq commands
(coqc, coqtop, coqdep, …) options \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}} or \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}} (see {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{By command line options}}}}).
Also, when an interactive Coq session starts, a library of root \sphinxcode{\sphinxupquote{Top}} is
started, unless option \sphinxcode{\sphinxupquote{\sphinxhyphen{}top}} or \sphinxcode{\sphinxupquote{\sphinxhyphen{}notop}} is set (see {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{By command line options}}}}).


\paragraph{Qualified identifiers}
\label{\detokenize{language/core/modules:qualified-identifiers}}\label{\detokenize{language/core/modules:qualified-names}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-qualid}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-field_ident}]{\sphinxcrossref{\DUrole{hole}{field\_ident}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/core/modules:grammar-token-field_ident}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-field_ident}]{\sphinxcrossref{\DUrole{hole}{field\_ident}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{.{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
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 Coq.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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).

\sphinxAtStartPar
Notice that the notion of absolute, partially qualified and short
names also applies to library filenames.

\sphinxAtStartPar
\sphinxstylestrong{Visibility}

\sphinxAtStartPar
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/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} and {\hyperref[\detokenize{language/core/modules:coq:cmd.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
Coq name table. Definitions with the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute are only accessible with
their fully qualified name (see {\hyperref[\detokenize{language/core/definitions:gallina-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Top\sphinxhyphen{}level definitions}}}}).

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{n}{nat}


\PYG{k+kn}{Definition} \PYG{n}{nat} \PYG{o}{:=} \PYG{n}{bool}\PYG{o}{.}
    \PYG{n}{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{n}{nat}


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


\PYG{n}{Locate} \PYG{n}{nat}\PYG{o}{.}
    \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{nat}
    \PYG{k+kn}{Inductive} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{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{n}{nat}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\sphinxstrong{See also:}
\nopagebreak


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




\paragraph{Libraries and filesystem}
\label{\detokenize{language/core/modules:libraries-and-filesystem}}\label{\detokenize{language/core/modules:id2}}
\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The questions described here have been subject to redesign in Coq 8.5.
Former versions of Coq use the same terminology to describe slightly different things.
\end{sphinxadmonition}

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

\sphinxAtStartPar
A logical prefix Lib can be associated with a physical path using
the command line option \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}} \sphinxcode{\sphinxupquote{path}} \sphinxcode{\sphinxupquote{Lib}}. All subfolders of path are
recursively associated with 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 Coq identifiers are skipped, and, by convention,
subdirectories named \sphinxcode{\sphinxupquote{CVS}} or \sphinxcode{\sphinxupquote{\_darcs}} are skipped too.

\sphinxAtStartPar
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 with 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.

\sphinxAtStartPar
Some folders have a special status and are automatically put in the
path. Coq commands automatically associate a logical path to files in
the repository tree rooted at the directory from where the command is
launched, \sphinxcode{\sphinxupquote{coqlib/user\sphinxhyphen{}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}[13]\sphinxAtStartFootnote
\sphinxnolinkurl{http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html}
%
\end{footnote})
with the same physical\sphinxhyphen{}to\sphinxhyphen{}logical translation and with an empty logical prefix.

\sphinxAtStartPar
The command line option \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}} is a variant of \sphinxcode{\sphinxupquote{\sphinxhyphen{}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
similar to the {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} command. For instance, \sphinxcode{\sphinxupquote{\sphinxhyphen{}R path Lib}}
associates the file \sphinxcode{\sphinxupquote{/path/foo/Bar/File.vo}} with 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}}, \sphinxcode{\sphinxupquote{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\sphinxhyphen{}
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}}}}).

\sphinxAtStartPar
There also exists another independent loadpath mechanism attached to
OCaml object files (\sphinxcode{\sphinxupquote{.cmo}} or \sphinxcode{\sphinxupquote{.cmxs}}) rather than Coq object
files as described above. The OCaml loadpath is managed using
the option \sphinxcode{\sphinxupquote{\sphinxhyphen{}I}} \sphinxcode{\sphinxupquote{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 {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Declare-ML-Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare ML 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.

\sphinxAtStartPar
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 Coq command
line options.


\subsubsection{Controlling the scope of commands with locality attributes}
\label{\detokenize{language/core/modules:controlling-the-scope-of-commands-with-locality-attributes}}\label{\detokenize{language/core/modules:controlling-locality-of-commands}}
\sphinxAtStartPar
Many commands have effects that apply only within a specific scope,
typically the section or the module in which the command was
called. Locality {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attributes}}}} can alter the scope of
the effect. Below, we give the semantics of each locality attribute
while noting a few exceptional commands for which {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} and
{\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attributes are interpreted differently.
\index{local (attribute)@\spxentry{local}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:attr.local}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{local}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}} limits the effect of the command to the
current scope (section or module).

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Local}} prefix is an alternative syntax for the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}}
attribute (see \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}).

\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
\sphinxAtStartPar
For some commands, this is the only locality supported within
sections (e.g., for {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Ltac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac}}}}} and
{\hyperref[\detokenize{proofs/automatic-tactics/auto:creating-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Hint}}}} commands).

\item {} 
\sphinxAtStartPar
For some commands, this is the default locality within
sections even though other locality attributes are supported
as well (e.g., for the {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command).

\end{itemize}
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
\sphinxstylestrong{Exception:} when {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} is applied to
{\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}, {\hyperref[\detokenize{language/core/definitions:coq:cmd.Theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} or their variants, its
semantics are different: it makes the defined objects available
only through their fully\sphinxhyphen{}qualified names rather than their
unqualified names after an {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}}.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{export (attribute)@\spxentry{export}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:attr.export}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{export}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}} makes the effect of the command
persist when the section is closed and applies the effect when the
module containing the command is imported.

\sphinxAtStartPar
Commands supporting this attribute include {\hyperref[\detokenize{language/core/basic:coq:cmd.Set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Set}}}}}, {\hyperref[\detokenize{language/core/basic:coq:cmd.Unset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unset}}}}}
and the {\hyperref[\detokenize{proofs/automatic-tactics/auto:creating-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Hint}}}} commands, although the latter
don't support it within sections.

\end{fulllineitems}\end{savenotes}

\index{global (attribute)@\spxentry{global}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/core/modules:coq:attr.global}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{global}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}} makes the effect of the command
persist even when the current section or module is closed.  Loading
the file containing the command (possibly transitively) applies the
effect of the command.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Global}} prefix is an alternative syntax for the
{\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attribute (see \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}).

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
\sphinxstylestrong{Exception:} for a few commands (like {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} and
{\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Ltac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac}}}}}), this attribute behaves like {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
We strongly discourage using the {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} locality
attribute because the transitive nature of file loading gives
the user little control. We recommend using the {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}}
locality attribute where it is supported.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\subsection{Primitive objects}
\label{\detokenize{language/core/primitive:primitive-objects}}\label{\detokenize{language/core/primitive::doc}}

\subsubsection{Primitive Integers}
\label{\detokenize{language/core/primitive:primitive-integers}}\label{\detokenize{language/core/primitive:id1}}
\sphinxAtStartPar
The language of terms features 63\sphinxhyphen{}bit machine integers as values. The type of
such a value is \sphinxstyleemphasis{axiomatized}; it is declared through the following sentence
(excerpt from the \sphinxcode{\sphinxupquote{\DUrole{name}{PrimInt63}}} module):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Primitive} \PYG{n}{int} \PYG{o}{:=} \PYG{o}{\PYGZsh{}}\PYG{n}{int63\PYGZus{}type}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This type can be understood as representing either unsigned or signed integers,
depending on which module is imported or, more generally, which scope is open.
\sphinxcode{\sphinxupquote{\DUrole{name}{Uint63}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{uint63\_scope}}} refer to the unsigned version, while \sphinxcode{\sphinxupquote{\DUrole{name}{Sint63}}}
and \sphinxcode{\sphinxupquote{\DUrole{name}{sint63\_scope}}} refer to the signed one.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{name}{PrimInt63}}} module declares the available operators for this type.
For instance, equality of two unsigned primitive integers can be determined using
the \sphinxcode{\sphinxupquote{\DUrole{name}{Uint63}\DUrole{operator}{.}\DUrole{name}{eqb}}} function, declared and specified as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Primitive} \PYG{n}{eqb} \PYG{o}{:=} \PYG{o}{\PYGZsh{}}\PYG{n}{int63\PYGZus{}eq}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{m \PYGZsq{}==\PYGZsq{} n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{eqb} \PYG{n}{m} \PYG{n}{n}\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}{:} \PYG{n}{uint63\PYGZus{}scope}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{eqb\PYGZus{}correct} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{i} \PYG{n}{j}\PYG{o}{,} \PYG{o}{(}\PYG{n}{i} \PYG{o}{=}\PYG{o}{=} \PYG{n}{j}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{uint63} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{i} \PYG{o}{=} \PYG{n}{j}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The complete set of such operators can be found in the \sphinxcode{\sphinxupquote{\DUrole{name}{PrimInt63}}} module.
The specifications and notations are in the \sphinxcode{\sphinxupquote{\DUrole{name}{Uint63}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{Sint63}}}
modules.

\sphinxAtStartPar
These primitive declarations are regular axioms. As such, they must be trusted and are listed by the
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Print} \DUrole{name}{Assumptions}}} command, as in the following example.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{From} \PYG{n}{Coq} \PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Uint63}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{one\PYGZus{}minus\PYGZus{}one\PYGZus{}is\PYGZus{}zero} \PYG{o}{:} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{uint63}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k}{apply} \PYG{n}{eqb\PYGZus{}correct}\PYG{o}{;} \PYG{k}{vm\PYGZus{}compute}\PYG{o}{;} \PYG{k+kp}{reflexivity}\PYG{o}{.} \PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{Assumptions} \PYG{n}{one\PYGZus{}minus\PYGZus{}one\PYGZus{}is\PYGZus{}zero}\PYG{o}{.}
    \PYG{n}{Axioms}\PYG{o}{:}
    \PYG{n}{sub} \PYG{o}{:} \PYG{n}{int} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{int} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{int}
    \PYG{n}{eqb\PYGZus{}correct} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{i} \PYG{n}{j} \PYG{o}{:} \PYG{n}{int}\PYG{o}{,} \PYG{o}{(}\PYG{n}{i} \PYG{o}{=}\PYG{o}{?} \PYG{n}{j}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{uint63} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{i} \PYG{o}{=} \PYG{n}{j}
    \PYG{n}{eqb} \PYG{o}{:} \PYG{n}{int} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{int} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
\end{sphinxVerbatim}

\sphinxAtStartPar
The reduction machines implement dedicated, efficient rules to reduce the
applications of these primitive operations.

\sphinxAtStartPar
The extraction of these primitives can be customized similarly to the extraction
of regular axioms (see {\hyperref[\detokenize{addendum/extraction:extraction}]{\sphinxcrossref{\DUrole{std,std-ref}{Program extraction}}}}). Nonetheless, the \sphinxcode{\sphinxupquote{\DUrole{name}{ExtrOCamlInt63}}}
module can be used when extracting to OCaml: it maps the Coq primitives to types
and functions of a \sphinxcode{\sphinxupquote{\DUrole{name}{Uint63}}} module (including signed functions for
\sphinxcode{\sphinxupquote{\DUrole{name}{Sint63}}} despite the name). That OCaml module is not produced by extraction.
Instead, it has to be provided by the user (if they want to compile or execute
the extracted code). For instance, an implementation of this module can be taken
from the kernel of Coq.

\sphinxAtStartPar
Literal values (at type \sphinxcode{\sphinxupquote{\DUrole{name}{Uint63}\DUrole{operator}{.}\DUrole{name}{int}}}) are extracted to literal OCaml values
wrapped into the \sphinxcode{\sphinxupquote{\DUrole{name}{Uint63}\DUrole{operator}{.}\DUrole{name}{of\_int}}} (resp. \sphinxcode{\sphinxupquote{\DUrole{name}{Uint63}\DUrole{operator}{.}\DUrole{name}{of\_int64}}}) constructor on
64\sphinxhyphen{}bit (resp. 32\sphinxhyphen{}bit) platforms. Currently, this cannot be customized (see the
function \sphinxcode{\sphinxupquote{\DUrole{name}{Uint63}\DUrole{operator}{.}\DUrole{name}{compile}}} from the kernel).


\subsubsection{Primitive Floats}
\label{\detokenize{language/core/primitive:primitive-floats}}\label{\detokenize{language/core/primitive:id2}}
\sphinxAtStartPar
The language of terms features Binary64 floating\sphinxhyphen{}point numbers as values.
The type of such a value is \sphinxstyleemphasis{axiomatized}; it is declared through the
following sentence (excerpt from the \sphinxcode{\sphinxupquote{\DUrole{name}{PrimFloat}}} module):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Primitive} \PYG{n}{float} \PYG{o}{:=} \PYG{o}{\PYGZsh{}}\PYG{n}{float64\PYGZus{}type}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This type is equipped with a few operators, that must be similarly declared.
For instance, the product of two primitive floats can be computed using the
\sphinxcode{\sphinxupquote{\DUrole{name}{PrimFloat}\DUrole{operator}{.}\DUrole{name}{mul}}} function, declared and specified as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Primitive} \PYG{n}{mul} \PYG{o}{:=} \PYG{o}{\PYGZsh{}}\PYG{n}{float64\PYGZus{}mul}\PYG{o}{.}
\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}{mul} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{:} \PYG{n}{float\PYGZus{}scope}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{mul\PYGZus{}spec} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{Prim2SF} \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{y}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{float} \PYG{o}{=} \PYG{n}{SF64mul} \PYG{o}{(}\PYG{n}{Prim2SF} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Prim2SF} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{\DUrole{name}{Prim2SF}}} is defined in the \sphinxcode{\sphinxupquote{\DUrole{name}{FloatOps}}} module.

\sphinxAtStartPar
The set of such operators is described in section {\hyperref[\detokenize{language/coq-library:floats-library}]{\sphinxcrossref{\DUrole{std,std-ref}{Floats library}}}}.

\sphinxAtStartPar
These primitive declarations are regular axioms. As such, they must be trusted, and are listed by the
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Print} \DUrole{name}{Assumptions}}} command.

\sphinxAtStartPar
The reduction machines ({\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}) implement
dedicated, efficient rules to reduce the applications of these primitive
operations, using the floating\sphinxhyphen{}point processor operators that are assumed
to comply with the IEEE 754 standard for floating\sphinxhyphen{}point arithmetic.

\sphinxAtStartPar
The extraction of these primitives can be customized similarly to the extraction
of regular axioms (see {\hyperref[\detokenize{addendum/extraction:extraction}]{\sphinxcrossref{\DUrole{std,std-ref}{Program extraction}}}}). Nonetheless, the \sphinxcode{\sphinxupquote{\DUrole{name}{ExtrOCamlFloats}}}
module can be used when extracting to OCaml: it maps the Coq primitives to types
and functions of a \sphinxcode{\sphinxupquote{\DUrole{name}{Float64}}} module. Said OCaml module is not produced by
extraction. Instead, it has to be provided by the user (if they want to compile
or execute the extracted code). For instance, an implementation of this module
can be taken from the kernel of Coq.

\sphinxAtStartPar
Literal values (of type \sphinxcode{\sphinxupquote{\DUrole{name}{Float64}\DUrole{operator}{.}\DUrole{name}{t}}}) are extracted to literal OCaml
values (of type \sphinxcode{\sphinxupquote{\DUrole{name}{float}}}) written in hexadecimal notation and
wrapped into the \sphinxcode{\sphinxupquote{\DUrole{name}{Float64}\DUrole{operator}{.}\DUrole{name}{of\_float}}} constructor, e.g.:
\sphinxcode{\sphinxupquote{\DUrole{name}{Float64}\DUrole{operator}{.}\DUrole{name}{of\_float} \DUrole{operator}{(}\DUrole{literal,number,integer}{0}\DUrole{name}{x1p}\DUrole{operator}{+}\DUrole{literal,number,integer}{0}\DUrole{operator}{)}}}.


\subsubsection{Primitive Arrays}
\label{\detokenize{language/core/primitive:primitive-arrays}}\label{\detokenize{language/core/primitive:id3}}
\sphinxAtStartPar
The language of terms features persistent arrays as values. The type of
such a value is \sphinxstyleemphasis{axiomatized}; it is declared through the following sentence
(excerpt from the \sphinxcode{\sphinxupquote{\DUrole{name}{PArray}}} module):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Primitive} \PYG{n}{array} \PYG{o}{:=} \PYG{o}{\PYGZsh{}}\PYG{n}{array\PYGZus{}type}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This type is equipped with a few operators, that must be similarly declared.
For instance, elements in an array can be accessed and updated using the
\sphinxcode{\sphinxupquote{\DUrole{name}{PArray}\DUrole{operator}{.}\DUrole{name}{get}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{PArray}\DUrole{operator}{.}\DUrole{keyword}{set}}} functions, declared and specified as
follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Primitive} \PYG{n}{get} \PYG{o}{:=} \PYG{o}{\PYGZsh{}}\PYG{n}{array\PYGZus{}get}\PYG{o}{.}
\PYG{n}{Primitive} \PYG{k}{set} \PYG{o}{:=} \PYG{o}{\PYGZsh{}}\PYG{n}{array\PYGZus{}set}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{t .[ i ]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{get} \PYG{n}{t} \PYG{n}{i}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{t .[ i \PYGZlt{}\PYGZhy{} a ]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{set} \PYG{n}{t} \PYG{n}{i} \PYG{n}{a}\PYG{o}{)}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{get\PYGZus{}set\PYGZus{}same} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{t} \PYG{n}{i} \PYG{o}{(}\PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{length} \PYG{n}{t}\PYG{o}{)} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{t}\PYG{o}{.}\PYG{o}{[}\PYG{n}{i}\PYG{o}{\PYGZlt{}\PYGZhy{}}\PYG{n}{a}\PYG{o}{]}\PYG{o}{.}\PYG{o}{[}\PYG{n}{i}\PYG{o}{]} \PYG{o}{=} \PYG{n}{a}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{get\PYGZus{}set\PYGZus{}other} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{t} \PYG{n}{i} \PYG{n}{j} \PYG{o}{(}\PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{i} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{j} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{t}\PYG{o}{.}\PYG{o}{[}\PYG{n}{i}\PYG{o}{\PYGZlt{}\PYGZhy{}}\PYG{n}{a}\PYG{o}{]}\PYG{o}{.}\PYG{o}{[}\PYG{n}{j}\PYG{o}{]} \PYG{o}{=} \PYG{n}{t}\PYG{o}{.}\PYG{o}{[}\PYG{n}{j}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The rest of these operators can be found in the \sphinxcode{\sphinxupquote{\DUrole{name}{PArray}}} module.

\sphinxAtStartPar
These primitive declarations are regular axioms. As such, they must be trusted and are listed by the
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Print} \DUrole{name}{Assumptions}}} command.

\sphinxAtStartPar
The reduction machines ({\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}) implement
dedicated, efficient rules to reduce the applications of these primitive
operations.

\sphinxAtStartPar
The extraction of these primitives can be customized similarly to the extraction
of regular axioms (see {\hyperref[\detokenize{addendum/extraction:extraction}]{\sphinxcrossref{\DUrole{std,std-ref}{Program extraction}}}}). Nonetheless, the \sphinxcode{\sphinxupquote{\DUrole{name}{ExtrOCamlPArray}}}
module can be used when extracting to OCaml: it maps the Coq primitives to types
and functions of a \sphinxcode{\sphinxupquote{\DUrole{name}{Parray}}} module. Said OCaml module is not produced by
extraction. Instead, it has to be provided by the user (if they want to compile
or execute the extracted code). For instance, an implementation of this module
can be taken from the kernel of Coq (see \sphinxcode{\sphinxupquote{kernel/parray.ml}}).

\sphinxAtStartPar
Coq's primitive arrays are persistent data structures. Semantically, a set operation
\sphinxcode{\sphinxupquote{t.{[}i <\sphinxhyphen{} a{]}}} represents a new array that has the same values as \sphinxcode{\sphinxupquote{t}}, except
at position \sphinxcode{\sphinxupquote{i}} where its value is \sphinxcode{\sphinxupquote{a}}. The array \sphinxcode{\sphinxupquote{t}} still exists, can
still be used and its values were not modified. Operationally, the implementation
of Coq's primitive arrays is optimized so that the new array \sphinxcode{\sphinxupquote{t.{[}i <\sphinxhyphen{} a{]}}} does not
copy all of \sphinxcode{\sphinxupquote{t}}. The details are in section 2.3 of {[}\hyperlink{cite.zebibliography:id56}{CF07}{]}.
In short, the implementation keeps one version of \sphinxcode{\sphinxupquote{t}} as an OCaml native array and
other versions as lists of modifications to \sphinxcode{\sphinxupquote{t}}. Accesses to the native array
version are constant time operations. However, accesses to versions where all the cells of
the array are modified have O(n) access time, the same as a list. The version that is kept as the native array
changes dynamically upon each get and set call: the current list of modifications
is applied to the native array and the lists of modifications of the other versions
are updated so that they still represent the same values.


\subsection{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
\sphinxAtStartPar
Matthieu Sozeau

\end{description}\end{quote}


\subsubsection{General Presentation}
\label{\detokenize{addendum/universe-polymorphism:general-presentation}}
\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The status of Universe Polymorphism is experimental.
\end{sphinxadmonition}

\sphinxAtStartPar
This section describes the universe polymorphic extension of Coq.
Universe polymorphism makes it possible to write generic definitions
making use of universes and reuse them at different and sometimes
incompatible universe levels.

\sphinxAtStartPar
A standard example of the difference between universe \sphinxstyleemphasis{polymorphic}
and \sphinxstyleemphasis{monomorphic} definitions is given by the identity function:

\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}

\sphinxAtStartPar
By default, {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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\sphinxhyphen{}apply the identity, we will get an
error:

\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{}identity.u0+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{}identity.u0\PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Indeed, the global level \sphinxcode{\sphinxupquote{Top.1}} would have to be strictly smaller than
itself for this self\sphinxhyphen{}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}{\sphinxhyphen{}>} \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}{\}}}}.

\sphinxAtStartPar
A universe polymorphic identity function binds its domain universe
level at the definition level instead of making it global.

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{About} \PYG{n}{pidentity}\PYG{o}{.}
    \PYG{n}{pidentity}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}}\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{k+kn}{Arguments} \PYG{n}{pidentity} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}
    \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}

\sphinxAtStartPar
It is then possible to reuse the constant at different levels, like
so:

\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}

\sphinxAtStartPar
Of course, the two instances of \sphinxcode{\sphinxupquote{\DUrole{name}{pidentity}}} in this definition are
different. This can be seen when the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Printing-Universes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Universes}}}}} flag is on:

\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}{selfpid}\PYG{o}{.}\PYG{n}{u0}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{o}{@}\PYG{n}{pidentity}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{selfpid}\PYG{o}{.}\PYG{n}{u1}\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}{selfpid}\PYG{o}{.}\PYG{n}{u1}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}selfpid.u1 selfpid.u0\PYGZcb{} |= selfpid.u1 \PYGZlt{} selfpid.u0 }\PYG{c}{*)}
    
    \PYG{k+kn}{Arguments} \PYG{n}{selfpid} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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{addendum/universe-polymorphism: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).

\sphinxAtStartPar
Inductive types can also be declared universes polymorphic on
universes appearing in their parameters or fields. A typical example
is given by monoids:

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{Monoid}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{unit\PYGZus{}monoid} \PYG{o}{:} \PYG{n}{Monoid} \PYG{o}{:=}
  \PYG{o}{\PYGZob{}|} \PYG{n}{mon\PYGZus{}car} \PYG{o}{:=} \PYG{n}{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}{|\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
From this we can build a definition for the monoid of \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}\sphinxhyphen{}monoids
(where multiplication would be given by the product of monoids).

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{monoid\PYGZus{}monoid}\PYG{o}{.}
    \PYG{n}{monoid\PYGZus{}monoid}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{=} 
    \PYG{o}{\PYGZob{}|}
      \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}{|\PYGZcb{}}
         \PYG{o}{:} \PYG{n}{Monoid}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ u |= Set \PYGZlt{} u }\PYG{c}{*)}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}}}.


\subsubsection{Polymorphic, Monomorphic}
\label{\detokenize{addendum/universe-polymorphism:polymorphic-monomorphic}}\index{universes(polymorphic) (attribute)@\spxentry{universes(polymorphic)}\spxextra{attribute}}\index{Polymorphic (attribute)@\spxentry{Polymorphic}\spxextra{attribute}}\index{Monomorphic (attribute)@\spxentry{Monomorphic}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}}\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:attr.Polymorphic}}\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:attr.Monomorphic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{universes(polymorphic\DUrole{repeat-wrapper}{\DUrole{repeat}{=~\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}})}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{boolean attribute}}}} can be used to control whether universe
polymorphism is enabled in the definition of an inductive type.
There is also a legacy syntax using the \sphinxcode{\sphinxupquote{Polymorphic}} prefix (see
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}) which, as shown in the examples, is more
commonly used.

\sphinxAtStartPar
When \sphinxcode{\sphinxupquote{universes(polymorphic=no)}} is used, global universe constraints
are produced, even when the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}} flag is
on. There is also a legacy syntax using the \sphinxcode{\sphinxupquote{Monomorphic}} prefix
(see \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}).

\end{fulllineitems}\end{savenotes}

\index{universes(monomorphic) (attribute)@\spxentry{universes(monomorphic)}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:attr.universes(monomorphic)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{universes(monomorphic)}}}}~
\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.13: }Use {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic=no)}}}}}
instead.

\end{fulllineitems}\end{savenotes}

\index{Universe Polymorphism (flag)@\spxentry{Universe Polymorphism}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~Polymorphism}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is off by default.  When it is on, new declarations are
polymorphic unless the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic=no)}}}}}
attribute is used to override the default.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Many other commands can be used to declare universe polymorphic or
monomorphic {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} depending on whether the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe
Polymorphism}}}}} flag is on or the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}}
attribute is used:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/definitions:coq:cmd.Lemma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Lemma}}}}}, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}}, etc. can be used to declare universe
polymorphic constants.

\item {} 
\sphinxAtStartPar
Using the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}} attribute with the
{\hyperref[\detokenize{language/core/sections:coq:cmd.Section}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Section}}}}} command will locally set the polymorphism flag inside
the section.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}}, {\hyperref[\detokenize{language/core/sections:coq:cmd.Context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Context}}}}}, {\hyperref[\detokenize{addendum/universe-polymorphism:coq:cmd.Universe}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe}}}}} and
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:cmd.Constraint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Constraint}}}}} in a section support polymorphism. See
{\hyperref[\detokenize{addendum/universe-polymorphism:universe-polymorphism-in-sections}]{\sphinxcrossref{\DUrole{std,std-ref}{Universe polymorphism and sections}}}} for more details.

\item {} 
\sphinxAtStartPar
Using the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}} attribute with the
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Resolve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Resolve}}}}} or {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Rewrite}}}}} commands will make
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} / {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} use the hint polymorphically, not at
a single instance.

\end{itemize}


\subsubsection{Cumulative, NonCumulative}
\label{\detokenize{addendum/universe-polymorphism:cumulative-noncumulative}}\label{\detokenize{addendum/universe-polymorphism:cumulative}}\index{universes(cumulative) (attribute)@\spxentry{universes(cumulative)}\spxextra{attribute}}\index{Cumulative (attribute)@\spxentry{Cumulative}\spxextra{attribute}}\index{NonCumulative (attribute)@\spxentry{NonCumulative}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}}\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:attr.Cumulative}}\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:attr.NonCumulative}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{universes(cumulative\DUrole{repeat-wrapper}{\DUrole{repeat}{=~\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}})}}}}
\sphinxAtStartPar
Polymorphic inductive types, coinductive types, variants and
records can be declared cumulative using this {\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{boolean attribute}}}}
or the legacy \sphinxcode{\sphinxupquote{Cumulative}} prefix (see \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}) which, as
shown in the examples, is more commonly used.

\sphinxAtStartPar
This means that two instances of the same inductive type (family)
are convertible based on the universe variances; they do not need
to be equal.

\sphinxAtStartPar
When the attribtue is off, the inductive type is non\sphinxhyphen{}cumulative
even if the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Polymorphic-Inductive-Cumulativity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Polymorphic Inductive Cumulativity}}}}} flag is on.
There is also a legacy syntax using the \sphinxcode{\sphinxupquote{NonCumulative}} prefix
(see \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}).

\sphinxAtStartPar
This means that two instances of the same inductive type (family)
are convertible only if all the universes are equal.
\index{The cumulative attribute can only be used in a polymorphic context (error)@\spxentry{The cumulative attribute can only be used in a polymorphic context}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:exn.The-cumulative-attribute-can-only-be-used-in-a-polymorphic-context}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~cumulative~attribute~can~only~be~used~in~a~polymorphic~context.}}}}
\sphinxAtStartPar
Using this attribute requires being in a polymorphic context,
i.e. either having the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}} flag on, or
having used the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}} attribute as
well.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\#{[} universes(polymorphic\DUrole{repeat-wrapper}{\DUrole{repeat}{= yes}\DUrole{notation-sup}{?}}), universes(cumulative\DUrole{repeat-wrapper}{\DUrole{repeat}{= \DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}}) {]}}}} can be
abbreviated into \sphinxcode{\sphinxupquote{\DUrole{notation}{\#{[} universes(polymorphic\DUrole{repeat-wrapper}{\DUrole{repeat}{= yes}\DUrole{notation-sup}{?}}, cumulative\DUrole{repeat-wrapper}{\DUrole{repeat}{= \DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}}) {]}}}}.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{universes(noncumulative) (attribute)@\spxentry{universes(noncumulative)}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:attr.universes(noncumulative)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{universes(noncumulative)}}}}~
\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.13: }Use {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative=no)}}}}} instead.

\end{fulllineitems}\end{savenotes}

\index{Polymorphic Inductive Cumulativity (flag)@\spxentry{Polymorphic Inductive Cumulativity}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is on (it is off by default), it makes all
subsequent \sphinxstyleemphasis{polymorphic} inductive definitions cumulative, unless
the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative=no)}}}}} attribute is
used to override the default.  It has no effect on \sphinxstyleemphasis{monomorphic} inductive definitions.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Consider the examples below.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Polymorphic} \PYG{n}{Cumulative} \PYG{k+kn}{Inductive} \PYG{n}{list} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list}
\PYG{o}{|} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{list}\PYG{o}{.}
    \PYG{k+kn}{Inductive} \PYG{n}{list}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\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}{u}\PYG{o}{)}\PYG{o}{\PYGZcb{}} \PYG{o}{:=}
        \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{|} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{c}{(*}\PYG{c}{ }\PYG{c}{*}\PYG{c}{u |=  }\PYG{c}{*)}
    
    \PYG{k+kn}{Arguments} \PYG{n}{list} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope}
    \PYG{k+kn}{Arguments} \PYG{n}{nil} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope}
    \PYG{k+kn}{Arguments} \PYG{n}{cons} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}
\end{sphinxVerbatim}

\sphinxAtStartPar
When printing \sphinxcode{\sphinxupquote{\DUrole{name}{list}}}, the universe context indicates the subtyping
constraints by prefixing the level names with symbols.

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{=}}, \sphinxcode{\sphinxupquote{+}} and \sphinxcode{\sphinxupquote{*}}.

\sphinxAtStartPar
Here we see that \sphinxcode{\sphinxupquote{\DUrole{name}{list}}} binds an irrelevant universe, so any two
instances of \sphinxcode{\sphinxupquote{\DUrole{name}{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.

\sphinxAtStartPar
See {\hyperref[\detokenize{language/core/conversion: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\sphinxhyphen{}trivial subtyping relation:

\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}

\PYG{n}{About} \PYG{n}{packType}\PYG{o}{.}
    \PYG{n}{packType}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ +u |=  }\PYG{c}{*)}
    
    \PYG{n}{packType} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{k+kn}{Inductive} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{packType}
\end{sphinxVerbatim}

\sphinxAtStartPar
\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*}

\paragraph{Specifying cumulativity}
\label{\detokenize{addendum/universe-polymorphism:specifying-cumulativity}}
\sphinxAtStartPar
The variance of the universe parameters for a cumulative inductive may be specified by the user.

\sphinxAtStartPar
For the following type, universe \sphinxcode{\sphinxupquote{a}} has its variance automatically
inferred (it is irrelevant), \sphinxcode{\sphinxupquote{b}} is required to be irrelevant,
\sphinxcode{\sphinxupquote{c}} is covariant and \sphinxcode{\sphinxupquote{d}} is invariant. With these annotations
\sphinxcode{\sphinxupquote{c}} and \sphinxcode{\sphinxupquote{d}} have less general variances than would be inferred.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Polymorphic} \PYG{n}{Cumulative} \PYG{k+kn}{Inductive} \PYG{n}{Dummy}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{o}{*}\PYG{n}{b} \PYG{o}{+}\PYG{n}{c} \PYG{o}{=}\PYG{n}{d}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{dummy}\PYG{o}{.}
    \PYG{n}{Dummy} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Dummy\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Dummy\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Dummy\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Dummy\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}

\PYG{n}{About} \PYG{n}{Dummy}\PYG{o}{.}
    \PYG{n}{Dummy}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{n}{b} \PYG{n}{c} \PYG{n}{d}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Prop}
    \PYG{c}{(*}\PYG{c}{ }\PYG{c}{*}\PYG{c}{a }\PYG{c}{*}\PYG{c}{b +c =d |=  }\PYG{c}{*)}
    
    \PYG{n}{Dummy} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{k+kn}{Inductive} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{Dummy}
\end{sphinxVerbatim}

\sphinxAtStartPar
Insufficiently restrictive variance annotations lead to errors:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Polymorphic} \PYG{n}{Cumulative} \PYG{k+kn}{Record} \PYG{n}{bad}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{o}{*}\PYG{n}{a}\PYG{o}{\PYGZcb{}} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{a}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZcb{}}\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}{variance} \PYG{k}{for} \PYG{n}{universe} \PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{45}\PYG{o}{:} \PYG{n}{expected} \PYG{o}{*} \PYG{n}{but} \PYG{n}{cannot} \PYG{n}{be} \PYG{n}{less} \PYG{n}{restrictive} \PYG{n}{than} \PYG{o}{+}\PYG{o}{.}
\end{sphinxVerbatim}


\paragraph{An example of a proof using cumulativity}
\label{\detokenize{addendum/universe-polymorphism:an-example-of-a-proof-using-cumulativity}}
\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}


\paragraph{Cumulativity Weak Constraints}
\label{\detokenize{addendum/universe-polymorphism:cumulativity-weak-constraints}}\index{Cumulativity Weak Constraints (flag)@\spxentry{Cumulativity Weak Constraints}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
When set, which is the default, this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} 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 \sphinxcode{\sphinxupquote{u}} and \sphinxcode{\sphinxupquote{v}} when neither is smaller than the other and
one is flexible causes them to be unified. Otherwise the constraint is
silently discarded.

\sphinxAtStartPar
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}\end{savenotes}



\subsubsection{Global and local universes}
\label{\detokenize{addendum/universe-polymorphism:global-and-local-universes}}
\sphinxAtStartPar
Each universe is declared in a global or local context 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}}}.


\subsubsection{Conversion and unification}
\label{\detokenize{addendum/universe-polymorphism:conversion-and-unification}}
\sphinxAtStartPar
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 {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{bodies}}}}
during conversion.

\sphinxAtStartPar
This is accomplished by changing one rule of unification, the first\sphinxhyphen{}
order approximation rule, which applies when two applicative terms
with the same head are compared. It tries to short\sphinxhyphen{}cut unfolding by
comparing the arguments directly. In case the {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} is universe
polymorphic, we allow this rule to fire only when unifying the
universes results in instantiating a so\sphinxhyphen{}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.


\subsubsection{Minimization}
\label{\detokenize{addendum/universe-polymorphism:minimization}}
\sphinxAtStartPar
Universe polymorphism with cumulativity tends to generate many useless
inclusion constraints in general. Typically at each application of a
polymorphic {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{id0} \PYG{o}{:=} \PYG{o}{@}\PYG{n}{pidentity} \PYG{n}{nat} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

\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{n}{nat}
\end{sphinxVerbatim}

\sphinxAtStartPar
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)@\spxentry{Universe Minimization ToSet}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Turning this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{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}\end{savenotes}



\subsubsection{Explicit Universes}
\label{\detokenize{addendum/universe-polymorphism:explicit-universes}}\label{\detokenize{addendum/universe-polymorphism:id1}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/universe-polymorphism:grammar-token-universe_name}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-universe_name}]{\sphinxcrossref{\DUrole{hole}{universe\_name}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Set}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Prop}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/universe-polymorphism:grammar-token-univ_annot}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_annot}]{\sphinxcrossref{\DUrole{hole}{univ\_annot}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{@\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-universe_level}]{\sphinxcrossref{\DUrole{hole}{universe\_level}}}}}\DUrole{notation-sup}{*}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/universe-polymorphism:grammar-token-universe_level}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-universe_level}]{\sphinxcrossref{\DUrole{hole}{universe\_level}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Set}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Prop}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Type}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/universe-polymorphism:grammar-token-univ_decl}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_decl}]{\sphinxcrossref{\DUrole{hole}{univ\_decl}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{@\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{+}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{| \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_constraint}]{\sphinxcrossref{\DUrole{hole}{univ\_constraint}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} \DUrole{repeat-wrapper}{\DUrole{repeat}{+}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/universe-polymorphism:grammar-token-cumul_univ_decl}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-cumul_univ_decl}]{\sphinxcrossref{\DUrole{hole}{cumul\_univ\_decl}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{@\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{+}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{=}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{*}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{+}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{| \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_constraint}]{\sphinxcrossref{\DUrole{hole}{univ\_constraint}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} \DUrole{repeat-wrapper}{\DUrole{repeat}{+}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/universe-polymorphism:grammar-token-univ_constraint}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_constraint}]{\sphinxcrossref{\DUrole{hole}{univ\_constraint}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-universe_name}]{\sphinxcrossref{\DUrole{hole}{universe\_name}}}} \DUrole{alternative}{\DUrole{alternative-block}{<}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{=}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<=}} {\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-universe_name}]{\sphinxcrossref{\DUrole{hole}{universe\_name}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The syntax has been extended to allow users to explicitly bind names
to universes and explicitly instantiate polymorphic definitions.
\index{Universe (command)@\spxentry{Universe}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:cmd.Universe}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
In the monomorphic case, declares new global universes
with the given names.  Global universe names live in a separate namespace.
The command supports the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}} attribute (or
the \sphinxcode{\sphinxupquote{Polymorphic}} legacy attribute) only in sections, meaning the universe
quantification will be discharged for each section definition
independently.
\index{Polymorphic universes can only be declared inside sections, use Monomorphic Universe instead (error)@\spxentry{Polymorphic universes can only be declared inside sections, use Monomorphic Universe instead}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:exn.Polymorphic-universes-can-only-be-declared-inside-sections,-use-Monomorphic-Universe-instead}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Polymorphic~universes~can~only~be~declared~inside~sections,~use~Monomorphic~Universe~instead.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Constraint (command)@\spxentry{Constraint}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:cmd.Constraint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Constraint~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_constraint}]{\sphinxcrossref{\DUrole{hole}{univ\_constraint}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
Declares new constraints between named universes.

\sphinxAtStartPar
If consistent, the constraints are then enforced in the global
environment. Like {\hyperref[\detokenize{addendum/universe-polymorphism:coq:cmd.Universe}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe}}}}}, it can be used with the
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}} attribute (or the \sphinxcode{\sphinxupquote{Polymorphic}}
legacy attribute) in sections only to declare constraints discharged at
section closing time. One cannot declare a global constraint on
polymorphic universes.
\index{Undeclared universe ‘ident’ (error)@\spxentry{Undeclared universe ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:exn.Undeclared-universe-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Undeclared~universe~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{Universe inconsistency (error)@\spxentry{Universe inconsistency}\spxextra{error}}

\begin{savenotes}\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{savenotes}

\index{Polymorphic universe constraints can only be declared inside sections, use Monomorphic Constraint instead (error)@\spxentry{Polymorphic universe constraints can only be declared inside sections, use Monomorphic Constraint instead}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:exn.Polymorphic-universe-constraints-can-only-be-declared-inside-sections,-use-Monomorphic-Constraint-instead}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Polymorphic~universe~constraints~can~only~be~declared~inside~sections,~use~Monomorphic~Constraint~instead}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\subsubsection{Printing universes}
\label{\detokenize{addendum/universe-polymorphism:printing-universes}}\label{\detokenize{addendum/universe-polymorphism:id2}}\index{Printing Universes (flag)@\spxentry{Printing Universes}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:flag.Printing-Universes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Universes}}}}
\sphinxAtStartPar
Turn this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} on to activate the display of the actual level of each
occurrence of \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}. See {\hyperref[\detokenize{language/core/sorts:sorts}]{\sphinxcrossref{\DUrole{std,std-ref}{Sorts}}}} for details. This wizard flag, in
combination with {\hyperref[\detokenize{proof-engine/vernacular-commands: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}\end{savenotes}

\index{Print Universes (command)@\spxentry{Print Universes}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism: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~\DUrole{repeat-wrapper}{\DUrole{repeat}{Subgraph~(~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{*}}~)}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This command can be used to print the constraints on the internal level
of the occurrences of \(\Type\) (see {\hyperref[\detokenize{language/core/sorts:sorts}]{\sphinxcrossref{\DUrole{std,std-ref}{Sorts}}}}).

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{Subgraph}}} clause limits the printed graph to the requested names (adjusting
constraints to preserve the implied transitive constraints between
kept universes).

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{Sorted}}} clause makes each universe
equivalent to a numbered label reflecting its level (with a linear
ordering) in the universe hierarchy.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} is an optional output filename.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{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 \sphinxcode{\sphinxupquote{string}} doesn’t end in \sphinxcode{\sphinxupquote{.dot}} or \sphinxcode{\sphinxupquote{.gv}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Polymorphic definitions}
\label{\detokenize{addendum/universe-polymorphism:polymorphic-definitions}}
\sphinxAtStartPar
For polymorphic definitions, the declaration of (all) universe levels
introduced by a definition uses the following syntax:

\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}

\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 |= i \PYGZlt{}= j }\PYG{c}{*)}
    
    \PYG{k+kn}{Arguments} \PYG{n}{le} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}{<=} \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{proofs/writing-proofs/proof-mode:coq:cmd.Show-Universes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Universes}}}}} to display the current context of universes.

\sphinxAtStartPar
It is possible to provide only some universe levels and let Coq infer the others
by adding a \sphinxcode{\sphinxupquote{\DUrole{operator}{+}}} in the list of bound universe levels:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Definition} \PYG{n}{foobar}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{:=} \PYG{k+kt}{Type}\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}{Universe} \PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{73}\PYG{o}{\PYGZcb{}} \PYG{k}{is} \PYG{n}{unbound}\PYG{o}{.}

\PYG{k+kn}{Definition} \PYG{n}{foobar}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u} \PYG{o}{+}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}} \PYG{o}{:=} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{n}{foobar} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Universes}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{n}{foobar}\PYG{o}{.}
    \PYG{n}{foobar}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u} \PYG{n}{u0}\PYG{o}{\PYGZcb{}} \PYG{o}{=} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u0}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ u u0 |= u0 \PYGZlt{} u }\PYG{c}{*)}
\end{sphinxVerbatim}

\sphinxAtStartPar
This can be used to find which universes need to be explicitly bound in a given
definition.

\sphinxAtStartPar
Definitions can also be instantiated explicitly, giving their full
instance:

\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}{|}\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{} |= k \PYGZlt{}= l }\PYG{c}{*)}
\end{sphinxVerbatim}

\sphinxAtStartPar
User\sphinxhyphen{}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.

\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}{78}\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}{78}\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}{79}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{78}\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}{79}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.79 Top.78\PYGZcb{} |= Top.78 \PYGZlt{}= Top.79 }\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}{80}\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}{80}\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}{80}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{80}\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}{80}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.80\PYGZcb{} |=  }\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}{83} \PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{83}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{83}\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}{83}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.83\PYGZcb{} |=  }\PYG{c}{*)}
\end{sphinxVerbatim}
\index{Strict Universe Declaration (flag)@\spxentry{Strict Universe Declaration}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Turning this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} 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}\end{savenotes}

\index{Private Polymorphic Universes (flag)@\spxentry{Private Polymorphic Universes}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:flag.Private-Polymorphic-Universes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Private~Polymorphic~Universes}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}, on by default, removes universes which appear only in
the {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} of an opaque polymorphic definition from the definition's
universe arguments. As such, no value needs to be provided for
these universes when instantiating the definition. Universe
constraints are automatically adjusted.

\sphinxAtStartPar
Consider the following definition:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{foo}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}}

\PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k+kp}{exact} \PYG{k+kt}{Type}\PYG{o}{.} \PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{k+kn}{Print} \PYG{n}{foo}\PYG{o}{.}
    \PYG{n}{foo}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{=} 
    \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{86}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ Public universes:}
\PYG{c}{    i |= Set \PYGZlt{} i}
\PYG{c}{    Private universes:}
\PYG{c}{    \PYGZob{}Top.86\PYGZcb{} |= Top.86 \PYGZlt{} i }\PYG{c}{*)}
\end{sphinxVerbatim}

\sphinxAtStartPar
The universe \sphinxcode{\sphinxupquote{\DUrole{name}{Top}\DUrole{operator}{.}\DUrole{name}{xxx}}} for the \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}} in the {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} cannot be accessed, we
only care that one exists for any instantiation of the universes
appearing in the type of \sphinxcode{\sphinxupquote{\DUrole{name}{foo}}}. This is guaranteed when the
transitive constraint \sphinxcode{\sphinxupquote{Set <= Top.xxx < i}} is verified. Then when
using the {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} we don't need to put a value for the inner
universe:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{foo}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{foo}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{87}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{87}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.87\PYGZcb{} |= Set \PYGZlt{} Top.87 }\PYG{c}{*)}
\end{sphinxVerbatim}

\sphinxAtStartPar
and when not looking at the {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} we don't mention the private
universe:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{About} \PYG{n}{foo}\PYG{o}{.}
    \PYG{n}{foo}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ i |= Set \PYGZlt{} i }\PYG{c}{*)}
    
    \PYG{n}{foo} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{n}{foo} \PYG{k}{is} \PYG{n}{opaque}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{foo}
\end{sphinxVerbatim}

\sphinxAtStartPar
To recover the same behaviour with regard to universes as
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Defined}}}, the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Private-Polymorphic-Universes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Private Polymorphic Universes}}}}} flag may
be unset:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Unset} \PYG{n}{Private} \PYG{k+kn}{Polymorphic} \PYG{n}{Universes}\PYG{o}{.}

\PYG{k+kn}{Lemma} \PYG{n}{bar} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.} \PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k+kp}{exact} \PYG{k+kt}{Type}\PYG{o}{.} \PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{88}\PYG{o}{\PYGZcb{}}
    
    
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{n}{About} \PYG{n}{bar}\PYG{o}{.}
    \PYG{n}{bar}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u} \PYG{n}{u0}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{u}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ u u0 |= u0 \PYGZlt{} u }\PYG{c}{*)}
    
    \PYG{n}{bar} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{n}{bar} \PYG{k}{is} \PYG{n}{opaque}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{bar}

\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{n}{bar}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}}\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}{Universe} \PYG{n}{instance} \PYG{n}{should} \PYG{k}{have} \PYG{n}{length} \PYG{l+m+mi}{2}\PYG{o}{.}

\PYG{k+kn}{Check} \PYG{n}{bar}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{bar}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{91}
    \PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{92}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{91}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.92 Top.91\PYGZcb{} |= Top.92 \PYGZlt{} Top.91 }\PYG{c}{*)}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that named universes are always public.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Private} \PYG{k+kn}{Polymorphic} \PYG{n}{Universes}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Strict} \PYG{k+kn}{Universe} \PYG{n}{Declaration}\PYG{o}{.}

\PYG{k+kn}{Lemma} \PYG{n}{baz} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{outer}\PYG{o}{\PYGZcb{}}\PYG{o}{.} \PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k+kp}{exact} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{inner}\PYG{o}{\PYGZcb{}}\PYG{o}{.} \PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{outer}\PYG{o}{\PYGZcb{}}
    
    
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{n}{About} \PYG{n}{baz}\PYG{o}{.}
    \PYG{n}{baz}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{outer} \PYG{n}{inner}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{outer}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ outer inner |= inner \PYGZlt{} outer }\PYG{c}{*)}
    
    \PYG{n}{baz} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{n}{baz} \PYG{k}{is} \PYG{n}{opaque}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{baz}
\end{sphinxVerbatim}

\end{fulllineitems}\end{savenotes}



\subsubsection{Universe polymorphism and sections}
\label{\detokenize{addendum/universe-polymorphism:universe-polymorphism-and-sections}}\label{\detokenize{addendum/universe-polymorphism:universe-polymorphism-in-sections}}
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variables}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variables}}}}}, {\hyperref[\detokenize{language/core/sections:coq:cmd.Context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Context}}}}}, {\hyperref[\detokenize{addendum/universe-polymorphism:coq:cmd.Universe}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe}}}}} and
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:cmd.Constraint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Constraint}}}}} in a section support polymorphism. This means that
the universe variables and their 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 with the variable.

\sphinxAtStartPar
It is possible to mix universe polymorphism and monomorphism in
sections, except in the following ways:
\begin{itemize}
\item {} 
\sphinxAtStartPar
no monomorphic constraint may refer to a polymorphic universe:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Foo}\PYG{o}{.}

  \PYG{k+kn}{Polymorphic} \PYG{k+kn}{Universe} \PYG{n}{i}\PYG{o}{.}
  \PYG{n}{Fail} \PYG{n}{Constraint} \PYG{n}{i} \PYG{o}{=} \PYG{n}{i}\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}{Cannot} \PYG{n}{add} \PYG{n}{monomorphic} \PYG{n}{constraints} \PYG{n}{which} \PYG{n}{refer} \PYG{n}{to} \PYG{n}{section} \PYG{n}{polymorphic} \PYG{n}{universes}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This includes constraints implicitly declared by commands such as
{\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}}, which may need to be used with universe
polymorphism activated (locally by attribute or globally by option):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{o}{(}\PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\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}{Cannot} \PYG{n}{add} \PYG{n}{monomorphic} \PYG{n}{constraints} \PYG{n}{which} \PYG{n}{refer} \PYG{n}{to} \PYG{n}{section} \PYG{n}{polymorphic} \PYG{n}{universes}\PYG{o}{.}

\PYG{k+kn}{Polymorphic} \PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{o}{(}\PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{A} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

\sphinxAtStartPar
(in the above example the anonymous \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}} constrains polymorphic
universe \sphinxcode{\sphinxupquote{\DUrole{name}{i}}} to be strictly smaller.)

\item {} 
\sphinxAtStartPar
no monomorphic {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} or inductive may be declared if polymorphic
universes or universe constraints are present.

\end{itemize}

\sphinxAtStartPar
These restrictions are required in order to produce a sensible result
when closing the section (the requirement on {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} and inductive types
is stricter than the one on constraints, because constants and
inductives are abstracted by \sphinxstyleemphasis{all} the section's polymorphic universes
and constraints).


\subsection{SProp (proof irrelevant propositions)}
\label{\detokenize{addendum/sprop:sprop-proof-irrelevant-propositions}}\label{\detokenize{addendum/sprop:sprop}}\label{\detokenize{addendum/sprop::doc}}
\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The status of strict propositions is experimental.

\sphinxAtStartPar
In particular, conversion checking through bytecode or native code
compilation currently does not understand proof irrelevance.
\end{sphinxadmonition}

\sphinxAtStartPar
This section describes the extension of Coq with definitionally
proof irrelevant propositions (types in the sort \(\SProp\), also
known as strict propositions) as described in
{[}\hyperlink{cite.zebibliography:id21}{GCST19}{]}.

\sphinxAtStartPar
Use of \(\SProp\) may be disabled by passing \sphinxcode{\sphinxupquote{\sphinxhyphen{}disallow\sphinxhyphen{}sprop}} to the
Coq program or by turning the {\hyperref[\detokenize{addendum/sprop:coq:flag.Allow-StrictProp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Allow StrictProp}}}}} flag off.
\index{Allow StrictProp (flag)@\spxentry{Allow StrictProp}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/sprop:coq:flag.Allow-StrictProp}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Allow~StrictProp}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} enables or disables the use of \(\SProp\).  It is enabled by default.
The command\sphinxhyphen{}line flag \sphinxcode{\sphinxupquote{\sphinxhyphen{}disallow\sphinxhyphen{}sprop}} disables \(\SProp\) at
startup.
\index{SProp is disallowed because the ""Allow StrictProp"" flag is off (error)@\spxentry{SProp is disallowed because the ""Allow StrictProp"" flag is off}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/sprop:coq:exn.SProp-is-disallowed-because-the-"Allow-StrictProp"-flag-is-off}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SProp~is~disallowed~because~the~"Allow~StrictProp"~flag~is~off.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Some of the definitions described in this document are available
through \sphinxcode{\sphinxupquote{Coq.Logic.StrictProp}}, which see.


\subsubsection{Basic constructs}
\label{\detokenize{addendum/sprop:basic-constructs}}
\sphinxAtStartPar
The purpose of \(\SProp\) is to provide types where all elements
are convertible:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Theorem} \PYG{n}{irrelevance} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{SProp}\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}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{,} \PYG{n}{P} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{SProp}
      \PYG{n}{P} \PYG{o}{:} \PYG{n}{A} \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{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\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}{P} \PYG{n}{y}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{intros} \PYG{o}{*} \PYG{n}{Hx} \PYG{o}{*}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{SProp}
      \PYG{n}{P} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{Hx} \PYG{o}{:} \PYG{n}{P} \PYG{n}{x}
      \PYG{n}{y} \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}{P} \PYG{n}{y}

\PYG{k+kp}{exact} \PYG{n}{Hx}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Since we have definitional {\hyperref[\detokenize{language/core/conversion:eta-expansion-sect}]{\sphinxcrossref{\DUrole{std,std-ref}{η\sphinxhyphen{}expansion}}}} for
functions, the property of being a type of definitionally irrelevant
values is impredicative, and so is \(\SProp\):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{n}{x}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{SProp}\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{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{n}{x}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{SProp}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{,} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{SProp}
\end{sphinxVerbatim}

\sphinxAtStartPar
In order to keep conversion tractable, cumulativity for \(\SProp\)
is forbidden, unless the {\hyperref[\detokenize{addendum/sprop:coq:flag.Cumulative-StrictProp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Cumulative StrictProp}}}}} flag is turned
on:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\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}{A} \PYG{o}{:} \PYG{k+kt}{SProp}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{SProp}\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}{Type}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}

\PYG{k+kn}{Set} \PYG{n}{Cumulative} \PYG{n}{StrictProp}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{SProp} \PYG{o}{=\PYGZgt{}} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
         \PYG{o}{:} \PYG{k+kt}{SProp} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}
\end{sphinxVerbatim}

\sphinxAtStartPar
We can explicitly lift strict propositions into the relevant world by
using a wrapping inductive type. The inductive stops definitional
proof irrelevance from escaping.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Box} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{box} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Box} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{n}{box} \PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{Box} \PYG{n}{A}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}refl} \PYG{o}{:} \PYG{n}{x} \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}{A} \PYG{o}{:} \PYG{k+kt}{SProp}
    \PYG{n}{x} \PYG{o}{:} \PYG{n}{Box} \PYG{n}{A}
    \PYG{n}{y} \PYG{o}{:} \PYG{n}{Box} \PYG{n}{A}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{eq\PYGZus{}refl}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x = x}\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}{x = y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{(}\PYG{n}{cannot} \PYG{n}{unify} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{and} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{y}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{box\PYGZus{}irrelevant} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{Box} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
  \PYG{o}{:=} \PYG{k}{match} \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{k}{with} \PYG{n}{box} \PYG{n}{x}\PYG{o}{,} \PYG{n}{box} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}refl} \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
In the other direction, we can use impredicativity to "squash" a
relevant type, making an irrelevant approximation.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{iSquash} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{SProp}
  \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{SProp}\PYG{o}{,} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{isquash} \PYG{n}{A} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{iSquash} \PYG{n}{A}
  \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{a} \PYG{n}{P} \PYG{n}{f} \PYG{o}{=\PYGZgt{}} \PYG{n}{f} \PYG{n}{a}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{iSquash\PYGZus{}sind} \PYG{n}{A} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{iSquash} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{isquash} \PYG{n}{A} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{iSquash} \PYG{n}{A}\PYG{o}{,} \PYG{n}{P} \PYG{n}{x}
  \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{(}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Or more conveniently (but equivalently)

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Squash} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{SProp} \PYG{o}{:=} \PYG{n}{squash} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Squash} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Most inductives types defined in \(\SProp\) are squashed types,
i.e. they can only be eliminated to construct proofs of other strict
propositions. Empty types are the only exception.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{sEmpty} \PYG{o}{:} \PYG{k+kt}{SProp} \PYG{o}{:=} \PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{sEmpty\PYGZus{}rect}\PYG{o}{.}
    \PYG{n}{sEmpty\PYGZus{}rect}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{sEmpty} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{sEmpty}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{n}{s}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Eliminators to strict propositions are called \sphinxcode{\sphinxupquote{foo\_sind}}, in the
same way that eliminators to propositions are called \sphinxcode{\sphinxupquote{foo\_ind}}.
\end{sphinxadmonition}

\sphinxAtStartPar
Primitive records in \(\SProp\) are allowed when fields are strict
propositions, for instance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Primitive} \PYG{k+kn}{Projections}\PYG{o}{.}
\PYG{k+kn}{Record} \PYG{n}{sProd} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{SProp} \PYG{o}{:=} \PYG{o}{\PYGZob{}} \PYG{n}{sfst} \PYG{o}{:} \PYG{n}{A}\PYG{o}{;} \PYG{n}{ssnd} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
On the other hand, to avoid having definitionally irrelevant types in
non\sphinxhyphen{}\(\SProp\) sorts (through record η\sphinxhyphen{}extensionality), primitive
records in relevant sorts must have at least one relevant field.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Warnings} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{+non\PYGZhy{}primitive\PYGZhy{}record}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\PYG{n}{Fail} \PYG{k+kn}{Record} \PYG{n}{rBox} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{rbox} \PYG{o}{\PYGZob{}} \PYG{n}{runbox} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZcb{}}\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}{record} \PYG{n}{rBox} \PYG{n}{could} \PYG{n}{not} \PYG{n}{be} \PYG{n}{defined} \PYG{k}{as} \PYG{n}{a} \PYG{n}{primitive} \PYG{n}{record}
    \PYG{o}{[}\PYG{n}{non}\PYG{o}{\PYGZhy{}}\PYG{n}{primitive}\PYG{o}{\PYGZhy{}}\PYG{n}{record}\PYG{o}{,}\PYG{n}{record}\PYG{o}{]}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Record} \PYG{n}{ssig} \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}{SProp}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{o}{\PYGZob{}} \PYG{n}{spr1} \PYG{o}{:} \PYG{n}{A}\PYG{o}{;} \PYG{n}{spr2} \PYG{o}{:} \PYG{n}{P} \PYG{n}{spr1} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that \sphinxcode{\sphinxupquote{rBox}} works as an emulated record, which is equivalent to
the Box inductive.


\subsubsection{Encodings for strict propositions}
\label{\detokenize{addendum/sprop:encodings-for-strict-propositions}}
\sphinxAtStartPar
The elimination for unit types can be encoded by a trivial function
thanks to proof irrelevance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{sUnit} \PYG{o}{:} \PYG{k+kt}{SProp} \PYG{o}{:=} \PYG{n}{stt}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{sUnit\PYGZus{}rect} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{sUnit}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{v}\PYG{o}{:}\PYG{n}{P} \PYG{n}{stt}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{sUnit}\PYG{o}{)} \PYG{o}{:} \PYG{n}{P} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{v}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
By using empty and unit types as base values, we can encode other
strict propositions. For instance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{is\PYGZus{}true} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{n}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{SProp} \PYG{o}{:=} \PYG{k}{if} \PYG{n}{b} \PYG{k}{then} \PYG{n}{sUnit} \PYG{k}{else} \PYG{n}{sEmpty}\PYG{o}{.}

\PYG{k+kn}{Definition} \PYG{n}{is\PYGZus{}true\PYGZus{}eq\PYGZus{}true} \PYG{n}{b} \PYG{o}{:} \PYG{n}{is\PYGZus{}true} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n+nb+bp}{true} \PYG{o}{=} \PYG{n}{b}
  \PYG{o}{:=} \PYG{k}{match} \PYG{n}{b} \PYG{k}{with}
     \PYG{o}{|} \PYG{n+nb+bp}{true} \PYG{o}{=\PYGZgt{}} \PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}refl}
     \PYG{o}{|} \PYG{n+nb+bp}{false} \PYG{o}{=\PYGZgt{}} \PYG{n}{sEmpty\PYGZus{}ind} \PYG{o}{\PYGZus{}}
     \PYG{k}{end}\PYG{o}{.}

\PYG{k+kn}{Definition} \PYG{n}{eq\PYGZus{}true\PYGZus{}is\PYGZus{}true} \PYG{n}{b} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n+nb+bp}{true}\PYG{o}{=}\PYG{n}{b}\PYG{o}{)} \PYG{o}{:} \PYG{n}{is\PYGZus{}true} \PYG{n}{b}
  \PYG{o}{:=} \PYG{k}{match} \PYG{n}{H} \PYG{k}{in} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{n}{x} \PYG{k}{return} \PYG{n}{is\PYGZus{}true} \PYG{n}{x} \PYG{k}{with} \PYG{n}{eq\PYGZus{}refl} \PYG{o}{=\PYGZgt{}} \PYG{n}{stt} \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Definitional UIP}
\label{\detokenize{addendum/sprop:definitional-uip}}\index{Definitional UIP (flag)@\spxentry{Definitional UIP}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/sprop:coq:flag.Definitional-UIP}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Definitional~UIP}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}, off by default, allows the declaration of non\sphinxhyphen{}squashed
inductive types with 1 constructor which takes no argument in
\(\SProp\). Since this includes equality types, it provides
definitional uniqueness of identity proofs.

\sphinxAtStartPar
Because squashing is a universe restriction, unsetting
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Universe-Checking}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Checking}}}}} is stronger than setting
{\hyperref[\detokenize{addendum/sprop:coq:flag.Definitional-UIP}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definitional UIP}}}}}.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Definitional UIP involves a special reduction rule through which
reduction depends on conversion. Consider the following code:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Definitional} \PYG{n}{UIP}\PYG{o}{.}

\PYG{k+kn}{Inductive} \PYG{n}{seq} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{SProp} \PYG{o}{:=}
  \PYG{n}{srefl} \PYG{o}{:} \PYG{n}{seq} \PYG{n}{a} \PYG{n}{a}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{e} \PYG{o}{:} \PYG{n}{seq} \PYG{l+m+mi}{0} \PYG{l+m+mi}{0}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{hidden\PYGZus{}arrow} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{e} \PYG{k}{return} \PYG{k+kn}{Set} \PYG{k}{with} \PYG{n}{srefl} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{k}{end}\PYG{o}{.}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{hidden\PYGZus{}arrow}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{)} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
By the usual reduction rules \sphinxcode{\sphinxupquote{\DUrole{name}{hidden\_arrow}}} is a stuck match, but
by proof irrelevance \sphinxcode{\sphinxupquote{\DUrole{name}{e}}} is convertible to \sphinxcode{\sphinxupquote{\DUrole{name}{srefl} \DUrole{literal,number,integer}{0}}} and then by
congruence \sphinxcode{\sphinxupquote{\DUrole{name}{hidden\_arrow}}} is convertible to \sphinxcode{\sphinxupquote{nat \sphinxhyphen{}> nat}}.

\sphinxAtStartPar
The special reduction reduces any match on a type which uses
definitional UIP when the indices are convertible to those of the
constructor. For \sphinxcode{\sphinxupquote{seq}}, this means a match on a value of type \sphinxcode{\sphinxupquote{seq x
y}} reduces if and only if \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} are convertible.

\sphinxAtStartPar
Such matches are indicated in the printed representation by inserting
a cast around the discriminee:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{n}{hidden\PYGZus{}arrow} \PYG{o}{=} \PYG{k}{match} \PYG{n}{e} \PYG{o}{:} \PYG{n}{seq} \PYG{l+m+mi}{0} \PYG{l+m+mi}{0} \PYG{k}{with}
                   \PYG{o}{|} \PYG{n}{srefl} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
                   \PYG{k}{end}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}


\paragraph{Non Termination with UIP}
\label{\detokenize{addendum/sprop:non-termination-with-uip}}
\sphinxAtStartPar
The special reduction rule of UIP combined with an impredicative sort
breaks termination of reduction
{[}\hyperlink{cite.zebibliography:id55}{AC19}{]}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{all\PYGZus{}eq} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{n}{Q}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{seq} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{.}
    \PYG{n}{all\PYGZus{}eq} \PYG{k}{is} \PYG{n}{declared}


\PYG{k+kn}{Definition} \PYG{n}{transport} \PYG{o}{(}\PYG{n}{P} \PYG{n}{Q}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{P}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y}\PYG{o}{:}\PYG{n}{Q}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Q}
\PYG{o}{:=} \PYG{k}{match} \PYG{n}{all\PYGZus{}eq} \PYG{n}{P} \PYG{n}{Q} \PYG{n}{x} \PYG{n}{y} \PYG{k}{with} \PYG{n}{srefl} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{transport} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Definition} \PYG{n}{top} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P}\PYG{o}{.}
    \PYG{n}{top} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Definition} \PYG{n}{c} \PYG{o}{:} \PYG{n}{top} \PYG{o}{:=}
  \PYG{k}{fun} \PYG{n}{P} \PYG{n}{p} \PYG{o}{=\PYGZgt{}}
  \PYG{n}{transport}
  \PYG{o}{(}\PYG{n}{top} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{top}\PYG{o}{)}
  \PYG{n}{P}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{top} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{(}\PYG{n}{top} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{top}\PYG{o}{)} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)} \PYG{n}{x}\PYG{o}{)}
  \PYG{n}{p}\PYG{o}{.}
    \PYG{n}{c} \PYG{k}{is} \PYG{n}{defined}


\PYG{n}{Fail} \PYG{n}{Timeout} \PYG{l+m+mi}{1} \PYG{n}{Eval} \PYG{k}{lazy} \PYG{k}{in} \PYG{n}{c} \PYG{o}{(}\PYG{n}{top} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{top}\PYG{o}{)} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)} \PYG{n}{c}\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}{Timeout}\PYG{o}{!}
\end{sphinxVerbatim}

\sphinxAtStartPar
The term \sphinxcode{\sphinxupquote{\DUrole{name}{c} \DUrole{operator}{(}\DUrole{name}{top} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{top}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{keyword}{fun} \DUrole{name}{x} \DUrole{operator}{=>} \DUrole{name}{x}\DUrole{operator}{)} \DUrole{name}{c}}} infinitely reduces to itself.


\subsubsection{Issues with non\sphinxhyphen{}cumulativity}
\label{\detokenize{addendum/sprop:issues-with-non-cumulativity}}
\sphinxAtStartPar
During normal term elaboration, we don't always know that a type is a
strict proposition early enough. For instance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{constant\PYGZus{}0} \PYG{o}{:} \PYG{o}{?}\PYG{o}{[}\PYG{n}{T}\PYG{o}{]} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{:=} \PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{sUnit} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
While checking the type of the constant, we only know that \sphinxcode{\sphinxupquote{?{[}T{]}}}
must inhabit some sort. Putting it in some floating universe \sphinxcode{\sphinxupquote{u}}
would disallow instantiating it by \sphinxcode{\sphinxupquote{sUnit : SProp}}.

\sphinxAtStartPar
In order to make the system usable without having to annotate every
instance of \(\SProp\), we consider \(\SProp\) to be a subtype
of every universe during elaboration (i.e. outside the kernel). Then
once we have a fully elaborated term it is sent to the kernel which
will check that we didn't actually need cumulativity of \(\SProp\)
(in the example above, \sphinxcode{\sphinxupquote{u}} doesn't appear in the final term).

\sphinxAtStartPar
This means that some errors will be delayed until \sphinxcode{\sphinxupquote{Qed}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{foo} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k}{pose} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{SProp} \PYG{o}{=\PYGZgt{}} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)}\PYG{o}{;} \PYG{k+kp}{exact} \PYG{n}{True}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Qed}\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}{A} \PYG{o}{:} \PYG{k+kt}{SProp}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{SProp}\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}{Type}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\index{Elaboration StrictProp Cumulativity (flag)@\spxentry{Elaboration StrictProp Cumulativity}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/sprop:coq:flag.Elaboration-StrictProp-Cumulativity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Elaboration~StrictProp~Cumulativity}}}}
\sphinxAtStartPar
Unset this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (it is on by default) to be strict with regard to
\(\SProp\) cumulativity during elaboration.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
The implementation of proof irrelevance uses inferred "relevance"
marks on binders to determine which variables are irrelevant. Together
with non\sphinxhyphen{}cumulativity this allows us to avoid retyping during
conversion. However during elaboration cumulativity is allowed and so
the algorithm may miss some irrelevance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Definition} \PYG{n}{late\PYGZus{}mark} \PYG{o}{:=} \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{n}{x} \PYG{n}{y} \PYG{o}{(}\PYG{n}{v}\PYG{o}{:}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{v} \PYG{o}{:} \PYG{n}{P} \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}{A} \PYG{o}{:} \PYG{k+kt}{SProp}
    \PYG{n}{P} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
    \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}
    \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
    \PYG{n}{v} \PYG{o}{:} \PYG{n}{P} \PYG{n}{x}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{v}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{P x}\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}{P y}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The binders for \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} are created before their type is known
to be \sphinxcode{\sphinxupquote{A}}, so they're not marked irrelevant. This can be avoided
with sufficient annotation of binders (see \sphinxcode{\sphinxupquote{irrelevance}} at the
beginning of this chapter) or by bypassing the conversion check in
tactics.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{late\PYGZus{}mark} \PYG{o}{:=} \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{SProp}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{n}{x} \PYG{n}{y} \PYG{o}{(}\PYG{n}{v}\PYG{o}{:}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
  \PYG{n}{ltac}\PYG{o}{:}\PYG{o}{(}\PYG{n}{exact\PYGZus{}no\PYGZus{}check} \PYG{n}{v}\PYG{o}{)} \PYG{o}{:} \PYG{n}{P} \PYG{n}{y}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The kernel will re\sphinxhyphen{}infer the marks on the fully elaborated term, and
so correctly converts \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}}.
\index{Bad relevance (warning)@\spxentry{Bad relevance}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/sprop:coq:warn.Bad-relevance}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bad~relevance}}}}
\sphinxAtStartPar
This is a developer warning, disabled by default. It is emitted by
the kernel when it is passed a term with incorrect relevance marks.
To avoid conversion issues as in \sphinxcode{\sphinxupquote{late\_mark}} you may wish to use
it to find when your tactics are producing incorrect marks.

\end{fulllineitems}\end{savenotes}

\index{Cumulative StrictProp (flag)@\spxentry{Cumulative StrictProp}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/sprop:coq:flag.Cumulative-StrictProp}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cumulative~StrictProp}}}}
\sphinxAtStartPar
Set this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (it is off by default) to make the kernel accept
cumulativity between \(\SProp\) and other universes. This makes
typechecking incomplete.

\end{fulllineitems}\end{savenotes}



\section{Language extensions}
\label{\detokenize{language/extensions/index:language-extensions}}\label{\detokenize{language/extensions/index:extensions}}\label{\detokenize{language/extensions/index::doc}}
\sphinxAtStartPar
Elaboration extends the language accepted by the Coq kernel to make it
easier to use.  For example, this lets the user omit most type
annotations because they can be inferred, call functions with implicit
arguments which will be inferred as well, extend the syntax with
notations, factorize branches when pattern\sphinxhyphen{}matching, etc.  In this
chapter, we present these language extensions and we give some
explanations on how this language is translated down to the core
language presented in the {\hyperref[\detokenize{language/core/index:core-language}]{\sphinxcrossref{\DUrole{std,std-ref}{previous chapter}}}}.


\subsection{Existential variables}
\label{\detokenize{language/extensions/evars:existential-variables}}\label{\detokenize{language/extensions/evars:id1}}\label{\detokenize{language/extensions/evars::doc}}
\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{language/extensions/evars:term-existential-variable}}Existential variables} represent as yet unknown
values.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/evars:grammar-token-term_evar}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/evars:grammar-token-term_evar}]{\sphinxcrossref{\DUrole{hole}{term\_evar}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{?{[} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{?{[} ?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{@\{ \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{;}} \}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Coq terms can include existential variables that represent unknown
subterms that are eventually replaced with actual subterms.

\sphinxAtStartPar
Existential variables are generated in place of unsolved 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 unsolved 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.

\sphinxAtStartPar
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.

\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}{X} \PYG{o}{?}\PYG{n}{y}
         \PYG{o}{:} \PYG{o}{?}\PYG{n}{X}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{X} \PYG{o}{:} \PYG{o}{[} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{X}\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{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{S}\PYG{o}{,} \PYG{o}{?}\PYG{n}{S0}\PYG{o}{)} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{S} \PYG{o}{=\PYGZgt{}} \PYG{o}{?}\PYG{n}{y}\PYG{o}{)}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{S}\PYG{o}{,} \PYG{o}{?}\PYG{n}{S0}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{S} \PYG{o}{:} \PYG{o}{[} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{S0} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{S} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{S} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{S0}\PYG{o}{]}
\end{sphinxVerbatim}

\sphinxAtStartPar
In the general case, when an existential variable \sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} appears
outside its context of definition, its instance, written in the
form \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}} \}}}}}, is appended to its name, indicating
how the variables of its defining context are instantiated.
Only the variables that are defined in another context are displayed:
this is why an existential variable used in the same context as its
context of definition is written with no instance.
This behaviour may be changed: see {\hyperref[\detokenize{language/extensions/evars:explicit-display-existentials}]{\sphinxcrossref{\DUrole{std,std-ref}{Explicit displaying of existential instances for pretty\sphinxhyphen{}printing}}}}.

\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{n}{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{n}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{k+kt}{Type}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{T}\PYG{o}{]}
\end{sphinxVerbatim}

\sphinxAtStartPar
Existential variables can be named by the user upon creation using
the syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{?{[}{\hyperref[\detokenize{language/core/basic: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\sphinxhyphen{}goal selector, see {\hyperref[\detokenize{proof-engine/ltac:goal-selectors}]{\sphinxcrossref{\DUrole{std,std-ref}{Goal selectors}}}}).

\index{\_@\spxentry{\_}}\ignorespaces 

\subsubsection{Inferable subterms}
\label{\detokenize{language/extensions/evars:inferable-subterms}}\label{\detokenize{language/extensions/evars:index-0}}
\sphinxAtStartPar
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.


\subsubsection{Explicit displaying of existential instances for pretty\sphinxhyphen{}printing}
\label{\detokenize{language/extensions/evars:explicit-displaying-of-existential-instances-for-pretty-printing}}\label{\detokenize{language/extensions/evars:explicit-display-existentials}}\index{Printing Existential Instances (flag)@\spxentry{Printing Existential Instances}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/evars:coq:flag.Printing-Existential-Instances}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Existential~Instances}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (off by default) activates the full display of how the
context of an existential variable is instantiated at each of the
occurrences of the existential variable.

\end{fulllineitems}\end{savenotes}


\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{n}{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{n}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{k+kt}{Type}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{|}\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{n}{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{n}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{k+kt}{Type}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{|}\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}


\subsubsection{Solving existential variables using tactics}
\label{\detokenize{language/extensions/evars:solving-existential-variables-using-tactics}}\label{\detokenize{language/extensions/evars:tactics-in-terms}}
\sphinxAtStartPar
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:(}}\sphinxcode{\sphinxupquote{tacexpr}}\sphinxcode{\sphinxupquote{)}}, the user
can put a tactic anywhere a term is expected. The order of resolution
is not specified and is implementation\sphinxhyphen{}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 \sphinxcode{\sphinxupquote{tacexpr}} can be any tactic
expression as described in {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac}}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{foo} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=} \PYG{n}{ltac}\PYG{o}{:}\PYG{o}{(}\PYG{k+kp}{exact} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{foo} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
This construction is useful when one wants to define complicated terms
using highly automated tactics without resorting to writing the proof\sphinxhyphen{}term
by means of the interactive proof engine.


\subsection{Implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:implicit-arguments}}\label{\detokenize{language/extensions/implicit-arguments:implicitarguments}}\label{\detokenize{language/extensions/implicit-arguments::doc}}
\sphinxAtStartPar
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/extensions/implicit-arguments:the-different-kinds-of-implicit-arguments}}

\paragraph{Implicit arguments inferable from the knowledge of other arguments of a function}
\label{\detokenize{language/extensions/implicit-arguments:implicit-arguments-inferable-from-the-knowledge-of-other-arguments-of-a-function}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
\sphinxstylestrong{Strict Implicit Arguments}

\sphinxAtStartPar
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).

\sphinxAtStartPar
For instance, the first argument of

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

\sphinxAtStartPar
in module \sphinxcode{\sphinxupquote{List.v}} is strict because \sphinxcode{\sphinxupquote{\DUrole{name}{list}}} is an inductive type and \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}
will always be inferable from the type \sphinxcode{\sphinxupquote{\DUrole{name}{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

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

\sphinxAtStartPar
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}{=>} \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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
fun n =\PYGZgt{} match n with 0 =\PYGZgt{} True | \PYGZus{} =\PYGZgt{} anything end
\end{sphinxVerbatim}

\sphinxAtStartPar
would be a solution of the inference problem.

\sphinxAtStartPar
\sphinxstylestrong{Contextual Implicit Arguments}

\sphinxAtStartPar
An implicit argument can be \sphinxstyleemphasis{contextual} or not. An implicit argument
is said to be \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:

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

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

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

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

\sphinxAtStartPar
\sphinxstylestrong{Reversible\sphinxhyphen{}Pattern Implicit Arguments}

\sphinxAtStartPar
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\sphinxhyphen{}
pattern implicit argument}. A typical example is the argument \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} of
nat\_rec in

\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}

\sphinxAtStartPar
(\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}}}).

\sphinxAtStartPar
See {\hyperref[\detokenize{language/extensions/implicit-arguments:controlling-rev-pattern-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reversible\sphinxhyphen{}pattern implicit arguments}}}} for the automatic declaration of reversible\sphinxhyphen{}pattern
implicit arguments.


\paragraph{Implicit arguments inferable by resolution}
\label{\detokenize{language/extensions/implicit-arguments:implicit-arguments-inferable-by-resolution}}
\sphinxAtStartPar
This corresponds to a class of non\sphinxhyphen{}dependent implicit arguments that
are solved based on the structure of their type only.


\subsubsection{Maximal and non\sphinxhyphen{}maximal insertion of implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:maximal-and-non-maximal-insertion-of-implicit-arguments}}
\sphinxAtStartPar
When a function is partially applied and the next argument to
apply is an implicit argument, the application can be interpreted in two ways.
If the next argument is declared as \sphinxstyleemphasis{maximally inserted}, the partial
application will include that argument.  Otherwise, the argument is
\sphinxstyleemphasis{non\sphinxhyphen{}maximally inserted} and the partial application will not include that argument.

\sphinxAtStartPar
Each implicit argument can be declared to be inserted maximally or non
maximally. In Coq, maximally inserted implicit arguments are written between curly braces
"\{ \}" and non\sphinxhyphen{}maximally inserted implicit arguments are written in square brackets "{[} {]}".


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{language/extensions/implicit-arguments:coq:flag.Maximal-Implicit-Insertion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Maximal Implicit Insertion}}}}}




\paragraph{Trailing Implicit Arguments}
\label{\detokenize{language/extensions/implicit-arguments:trailing-implicit-arguments}}
\sphinxAtStartPar
An implicit argument is considered \sphinxstyleemphasis{trailing} when all following arguments are
implicit. Trailing implicit arguments must be declared as maximally inserted;
otherwise they would never be inserted.
\index{Argument ‘name’ is a trailing implicit, so it can't be declared non maximal. Please use \sphinxleftcurlybrace{} \sphinxrightcurlybrace{} instead of {[} {]} (error)@\spxentry{Argument ‘name’ is a trailing implicit, so it can't be declared non maximal. Please use \sphinxleftcurlybrace{} \sphinxrightcurlybrace{} instead of {[} {]}}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:exn.Argument-_u2018name_u2019-is-a-trailing-implicit,-so-it-can't-be-declared-non-maximal.-Please-use-_-_-instead-of-_-_}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Argument~{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}~is~a~trailing~implicit,~so~it~can\textquotesingle{}t~be~declared~non~maximal.~Please~use~\{~\}~instead~of~{[}~{]}.}}}}
\sphinxAtStartPar
For instance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Definition} \PYG{n}{double} \PYG{o}{[}\PYG{n}{n}\PYG{o}{]} \PYG{o}{:=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{n}\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}{Argument} \PYG{n}{n} \PYG{k}{is} \PYG{n}{a} \PYG{n}{trailing} \PYG{n}{implicit}\PYG{o}{,} \PYG{n}{so} \PYG{n}{it} \PYG{n}{can\PYGZsq{}t} \PYG{n}{be} \PYG{n}{declared} \PYG{n}{non} \PYG{n}{maximal}\PYG{o}{.}
    \PYG{n}{Please} \PYG{n}{use} \PYG{o}{\PYGZob{}} \PYG{o}{\PYGZcb{}} \PYG{n}{instead} \PYG{k}{of} \PYG{o}{[} \PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\end{fulllineitems}\end{savenotes}



\subsubsection{Casual use of implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:casual-use-of-implicit-arguments}}
\sphinxAtStartPar
If an argument of a function application can be inferred from the type
of the other arguments, the user can force inference of the argument
by replacing it with \sphinxcode{\sphinxupquote{\_}}.
\index{Cannot infer a term for this placeholder. (Casual use of implicit arguments) (error)@\spxentry{Cannot infer a term for this placeholder. (Casual use of implicit arguments)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments: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.}}}}
\sphinxAtStartPar
Coq was not able to deduce an instantiation of a “\_”.

\end{fulllineitems}\end{savenotes}



\subsubsection{Declaration of implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:declaration-of-implicit-arguments}}\label{\detokenize{language/extensions/implicit-arguments:declare-implicit-args}}
\sphinxAtStartPar
Implicit arguments can be declared when a function is declared or
afterwards, using the {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command.


\paragraph{Implicit Argument Binders}
\label{\detokenize{language/extensions/implicit-arguments:implicit-argument-binders}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/implicit-arguments:grammar-token-implicit_binders}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-implicit_binders}]{\sphinxcrossref{\DUrole{hole}{implicit\_binders}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
In the context of a function definition, these forms specify that
{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} is an implicit argument.  The first form, with curly
braces, makes {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} a maximally inserted implicit argument.  The second
form, with square brackets, makes {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} a non\sphinxhyphen{}maximally inserted implicit argument.

\sphinxAtStartPar
For example:

\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}

\sphinxAtStartPar
declares the argument \sphinxcode{\sphinxupquote{A}} of \sphinxcode{\sphinxupquote{id}} as a maximally
inserted implicit argument. \sphinxcode{\sphinxupquote{A}} may be omitted
in applications of \sphinxcode{\sphinxupquote{id}} but may be specified if needed:

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\sphinxAtStartPar
For non\sphinxhyphen{}maximally inserted implicit arguments, use square brackets:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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{n}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{list} \PYG{n}{B} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}
  \PYG{o}{|} \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}{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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{4}\PYG{n}{th} \PYG{n}{argument}\PYG{o}{)}


\PYG{k+kn}{Print} \PYG{k+kn}{Implicit} \PYG{n}{map}\PYG{o}{.}
    \PYG{n}{map} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{[}\PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{]}\PYG{o}{,} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{n}{B}
    
    \PYG{k+kn}{Arguments} \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{n}{are} \PYG{n}{implicit}
\end{sphinxVerbatim}

\sphinxAtStartPar
For (co\sphinxhyphen{})inductive datatype
declarations, the semantics are the following: an inductive parameter
declared as an implicit argument need not be repeated in the inductive
definition and will become implicit for the inductive type and the constructors.
For example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{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}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list}
\PYG{o}{|} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list}\PYG{o}{.}
    \PYG{n}{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{n}{list\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Print} \PYG{n}{list}\PYG{o}{.}
    \PYG{k+kn}{Inductive} \PYG{n}{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{n}{list} \PYG{o}{|} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list}\PYG{o}{.}
    
    \PYG{k+kn}{Arguments} \PYG{n}{list} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope}
    \PYG{k+kn}{Arguments} \PYG{n}{nil} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope}
    \PYG{k+kn}{Arguments} \PYG{n}{cons} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}
\end{sphinxVerbatim}

\sphinxAtStartPar
One can always specify the parameter if it is not uniform using the
usual implicit arguments disambiguation syntax.

\sphinxAtStartPar
The syntax is also supported in internal binders. For instance, in the
following kinds of expressions, the type of each declaration present
in \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}}}} can be bracketed to mark the declaration as
implicit:
* \sphinxcode{\sphinxupquote{\DUrole{notation}{fun ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}, {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}) => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}},
* \sphinxcode{\sphinxupquote{\DUrole{notation}{forall ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}, {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}), {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}},
* \sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}},
* \sphinxcode{\sphinxupquote{\DUrole{notation}{fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and
* \sphinxcode{\sphinxupquote{\DUrole{notation}{cofix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\sphinxAtStartPar
Here is an example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{Ax} \PYG{o}{:}
  \PYG{k}{forall} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{A} \PYG{o}{*} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,}
  \PYG{k}{let} \PYG{n}{g} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,}\PYG{n}{y}\PYG{o}{)} \PYG{k}{in}
  \PYG{n}{f} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{g} \PYG{l+m+mi}{0} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{Ax} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}
\index{Ignoring implicit binder declaration in unexpected position (warning)@\spxentry{Ignoring implicit binder declaration in unexpected position}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:warn.Ignoring-implicit-binder-declaration-in-unexpected-position}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ignoring~implicit~binder~declaration~in~unexpected~position}}}}
\sphinxAtStartPar
This is triggered when setting an argument implicit in an
expression which does not correspond to the type of an assumption
or to the {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} of a definition. Here is an example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{f} \PYG{o}{:=} \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{y}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{0}\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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{4}\PYG{n}{th} \PYG{n}{argument}\PYG{o}{)}
    \PYG{n}{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{n}{list\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Ax} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{24}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{25}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Definition} \PYG{n}{f} \PYG{o}{:=} \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{y}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}                         \PYG{o}{\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{Ignoring} \PYG{n}{implicit} \PYG{n}{binder} \PYG{n}{declaration} \PYG{k}{in} \PYG{n}{unexpected} \PYG{n}{position}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{unexpected}\PYG{o}{\PYGZhy{}}\PYG{n}{implicit}\PYG{o}{\PYGZhy{}}\PYG{n}{declaration}\PYG{o}{,}\PYG{n}{syntax}\PYG{o}{]}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\end{fulllineitems}\end{savenotes}

\index{Making shadowed name of implicit argument accessible by position (warning)@\spxentry{Making shadowed name of implicit argument accessible by position}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:warn.Making-shadowed-name-of-implicit-argument-accessible-by-position}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Making~shadowed~name~of~implicit~argument~accessible~by~position}}}}
\sphinxAtStartPar
This is triggered when two variables of same name are set implicit
in the same block of binders, in which case the first occurrence is
considered to be unnamed. Here is an example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k}{let} \PYG{n}{g} \PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{x}\PYG{o}{=}\PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{x}\PYG{o}{=}\PYG{n}{x}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{x} \PYG{k}{in} \PYG{l+m+mi}{0}\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}{50}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Check} \PYG{k}{let} \PYG{n}{g} \PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{x}\PYG{o}{=}\PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{x}\PYG{o}{=}\PYG{n}{x}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{x} \PYG{k}{in} \PYG{l+m+mi}{0}\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{n}{Warning}\PYG{o}{:} \PYG{n}{Making} \PYG{n}{shadowed} \PYG{n}{name} \PYG{k}{of} \PYG{n}{implicit} \PYG{n}{argument} \PYG{n}{accessible} \PYG{k+kp}{by} \PYG{n}{position}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{shadowed}\PYG{o}{\PYGZhy{}}\PYG{n}{implicit}\PYG{o}{\PYGZhy{}}\PYG{n}{name}\PYG{o}{,}\PYG{n}{syntax}\PYG{o}{]}
    \PYG{k}{let} \PYG{n}{g} \PYG{o}{:=} \PYG{k}{fun} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x0} \PYG{o}{:} \PYG{o}{?}\PYG{n}{A}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{x0}\PYG{o}{:=}\PYG{n}{x}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{x0} \PYG{o}{=} \PYG{n}{x0}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{x0} \PYG{k}{in} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{n}{nat}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{A} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x0} \PYG{o}{:} \PYG{n}{nat}  \PYG{n}{H} \PYG{o}{:} \PYG{n}{x0} \PYG{o}{=} \PYG{n}{x0}  \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{A} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{k+kt}{Type}\PYG{o}{]} \PYG{o}{(}\PYG{n}{x} \PYG{n}{cannot} \PYG{n}{be} \PYG{n}{used}\PYG{o}{)}
\end{sphinxVerbatim}

\end{fulllineitems}\end{savenotes}



\paragraph{Mode for automatic declaration of implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:mode-for-automatic-declaration-of-implicit-arguments}}\index{Implicit Arguments (flag)@\spxentry{Implicit Arguments}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Implicit-Arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Implicit~Arguments}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (off by default) allows to systematically declare implicit
the arguments detectable as such. Auto\sphinxhyphen{}detection of implicit arguments is
governed by flags controlling whether strict and contextual implicit
arguments have to be considered or not.

\end{fulllineitems}\end{savenotes}



\paragraph{Controlling strict implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:controlling-strict-implicit-arguments}}\label{\detokenize{language/extensions/implicit-arguments:controlling-strict-implicit-args}}\index{Strict Implicit (flag)@\spxentry{Strict Implicit}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Strict-Implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Strict~Implicit}}}}
\sphinxAtStartPar
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\sphinxhyphen{}strict
implicit arguments. To relax this constraint and to set
implicit all non strict implicit arguments by default, you can turn this
{\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} off.

\end{fulllineitems}\end{savenotes}

\index{Strongly Strict Implicit (flag)@\spxentry{Strongly Strict Implicit}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Strongly-Strict-Implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Strongly~Strict~Implicit}}}}
\sphinxAtStartPar
Use this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (off by default) to capture exactly the strict implicit
arguments and no more than the strict implicit arguments.

\end{fulllineitems}\end{savenotes}



\paragraph{Controlling contextual implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:controlling-contextual-implicit-arguments}}\label{\detokenize{language/extensions/implicit-arguments:controlling-contextual-implicit-args}}\index{Contextual Implicit (flag)@\spxentry{Contextual Implicit}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Contextual-Implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Contextual~Implicit}}}}
\sphinxAtStartPar
By default, Coq does not automatically set implicit the contextual
implicit arguments. You can turn this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} on to tell Coq to also
infer contextual implicit argument.

\end{fulllineitems}\end{savenotes}



\paragraph{Controlling reversible\sphinxhyphen{}pattern implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:controlling-reversible-pattern-implicit-arguments}}\label{\detokenize{language/extensions/implicit-arguments:controlling-rev-pattern-implicit-args}}\index{Reversible Pattern Implicit (flag)@\spxentry{Reversible Pattern Implicit}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Reversible-Pattern-Implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reversible~Pattern~Implicit}}}}
\sphinxAtStartPar
By default, Coq does not automatically set implicit the reversible\sphinxhyphen{}pattern
implicit arguments. You can turn this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} on to tell Coq to also infer
reversible\sphinxhyphen{}pattern implicit argument.

\end{fulllineitems}\end{savenotes}



\paragraph{Controlling the insertion of implicit arguments not followed by explicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:controlling-the-insertion-of-implicit-arguments-not-followed-by-explicit-arguments}}\label{\detokenize{language/extensions/implicit-arguments:controlling-insertion-implicit-args}}\index{Maximal Implicit Insertion (flag)@\spxentry{Maximal Implicit Insertion}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Maximal-Implicit-Insertion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Maximal~Implicit~Insertion}}}}
\sphinxAtStartPar
Assuming the implicit argument mode is on, this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (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}\end{savenotes}



\paragraph{Combining manual declaration and automatic declaration}
\label{\detokenize{language/extensions/implicit-arguments:combining-manual-declaration-and-automatic-declaration}}
\sphinxAtStartPar
When some arguments are manually specified implicit with binders in a definition
and the automatic declaration mode in on, the manual implicit arguments are added to the
automatically declared ones.

\sphinxAtStartPar
In that case, and when the flag {\hyperref[\detokenize{language/extensions/implicit-arguments:coq:flag.Maximal-Implicit-Insertion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Maximal Implicit Insertion}}}}} is set to off,
some trailing implicit arguments can be inferred to be non\sphinxhyphen{}maximally inserted. In
this case, they are converted to maximally inserted ones.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Implicit} \PYG{k+kn}{Arguments}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{eq0\PYGZus{}le0} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{eq0\PYGZus{}le0} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Print} \PYG{k+kn}{Implicit} \PYG{n}{eq0\PYGZus{}le0}\PYG{o}{.}
    \PYG{n}{eq0\PYGZus{}le0} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{[}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{]}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{Argument} \PYG{n}{n} \PYG{k}{is} \PYG{n}{implicit}

\PYG{k+kn}{Axiom} \PYG{n}{eq0\PYGZus{}le0\PYGZsq{}} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{n}{x} \PYG{o}{:} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{Argument} \PYG{n}{n} \PYG{k}{is} \PYG{n}{a} \PYG{n}{trailing} \PYG{n}{implicit}\PYG{o}{,} \PYG{n}{so} \PYG{n}{it} \PYG{n}{has} \PYG{n}{been} \PYG{n}{declared} \PYG{n}{maximally}
    \PYG{n}{inserted}\PYG{o}{.}
    \PYG{n}{eq0\PYGZus{}le0\PYGZsq{}} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Print} \PYG{k+kn}{Implicit} \PYG{n}{eq0\PYGZus{}le0\PYGZsq{}}\PYG{o}{.}
    \PYG{n}{eq0\PYGZus{}le0\PYGZsq{}} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{k+kn}{Arguments} \PYG{n}{n}\PYG{o}{,} \PYG{n}{x} \PYG{n}{are} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Explicit applications}
\label{\detokenize{language/extensions/implicit-arguments:explicit-applications}}\label{\detokenize{language/extensions/implicit-arguments:id1}}
\sphinxAtStartPar
In presence of non\sphinxhyphen{}strict or contextual arguments, or in presence of
partial applications, the synthesis of implicit arguments may fail, so
one may have to explicitly give certain implicit arguments of an
application. Use the \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} form of {\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{arg}}}}} to do so,
where {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the name of the implicit argument and {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
is its corresponding explicit term. Alternatively, one can deactivate
the hiding of implicit arguments for a single function application using the
\sphinxcode{\sphinxupquote{\DUrole{notation}{@{\hyperref[\detokenize{language/core/basic:grammar-token-qualid_annotated}]{\sphinxcrossref{\DUrole{hole}{qualid\_annotated}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term1}]{\sphinxcrossref{\DUrole{hole}{term1}}}}}\DUrole{notation-sup}{+}}}}} form of {\hyperref[\detokenize{language/core/assumptions:grammar-token-term_application}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term\_application}}}}}.

\begin{sphinxadmonition}{note}{Example: Syntax for explicitly giving implicit arguments (continued)}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \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{n}{eq0\PYGZus{}le0} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{Argument} \PYG{n}{n} \PYG{k}{is} \PYG{n}{a} \PYG{n}{trailing} \PYG{n}{implicit}\PYG{o}{,} \PYG{n}{so} \PYG{n}{it} \PYG{n}{has} \PYG{n}{been} \PYG{n}{declared} \PYG{n}{maximally}
    \PYG{n}{inserted}\PYG{o}{.}
    \PYG{n}{eq0\PYGZus{}le0\PYGZsq{}} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{X} \PYG{k}{is} \PYG{n}{declared}
    \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}{Parameters} \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{k+kn}{Implicit} \PYG{n}{p}\PYG{o}{.}
    \PYG{n}{p} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{[}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{X}\PYG{o}{]}\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}{Parameters} \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{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{Displaying implicit arguments}
\label{\detokenize{language/extensions/implicit-arguments:displaying-implicit-arguments}}\label{\detokenize{language/extensions/implicit-arguments:displaying-implicit-args}}\index{Print Implicit (command)@\spxentry{Print Implicit}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:cmd.Print-Implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Implicit~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}
\sphinxAtStartPar
Displays the implicit arguments associated with an object,
identifying which arguments are applied maximally or not.

\end{fulllineitems}\end{savenotes}



\subsubsection{Displaying implicit arguments when pretty\sphinxhyphen{}printing}
\label{\detokenize{language/extensions/implicit-arguments:displaying-implicit-arguments-when-pretty-printing}}\index{Printing Implicit (flag)@\spxentry{Printing Implicit}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Printing-Implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Implicit}}}}
\sphinxAtStartPar
By default, the basic pretty\sphinxhyphen{}printing rules hide the inferable implicit
arguments of an application. Turn this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} on to force printing all
implicit arguments.

\end{fulllineitems}\end{savenotes}

\index{Printing Implicit Defensive (flag)@\spxentry{Printing Implicit Defensive}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Printing-Implicit-Defensive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Implicit~Defensive}}}}
\sphinxAtStartPar
By default, the basic pretty\sphinxhyphen{}printing rules display 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 {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} off.

\end{fulllineitems}\end{savenotes}



\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}}.




\subsubsection{Interaction with subtyping}
\label{\detokenize{language/extensions/implicit-arguments:interaction-with-subtyping}}
\sphinxAtStartPar
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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{n}{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{n}{Cannot} \PYG{n}{enforce} \PYG{k+kn}{Set}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
but succeeds in

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k+kt}{Prop} \PYG{o}{=} \PYG{n}{nat}\PYG{o}{.}
    \PYG{k+kt}{Prop} \PYG{o}{=} \PYG{n}{nat}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}


\subsubsection{Deactivation of implicit arguments for parsing}
\label{\detokenize{language/extensions/implicit-arguments:deactivation-of-implicit-arguments-for-parsing}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/implicit-arguments:grammar-token-term_explicit}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-term_explicit}]{\sphinxcrossref{\DUrole{hole}{term\_explicit}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{@ {\hyperref[\detokenize{language/core/basic:grammar-token-qualid_annotated}]{\sphinxcrossref{\DUrole{hole}{qualid\_annotated}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
This syntax can be used to disable implicit arguments for a single
function.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The function \sphinxcode{\sphinxupquote{id}} has one implicit argument and one explicit
argument.

\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{n}{nat}

\PYG{k+kn}{Definition} \PYG{n}{id\PYGZsq{}} \PYG{o}{:=} \PYG{o}{@}\PYG{n}{id}\PYG{o}{.}
    \PYG{n}{id\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
The function \sphinxcode{\sphinxupquote{id'}} has no implicit argument.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{id\PYGZsq{}} \PYG{n}{nat} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{id\PYGZsq{}} \PYG{n}{nat} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Parsing Explicit (flag)@\spxentry{Parsing Explicit}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Parsing-Explicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Parsing~Explicit}}}}
\sphinxAtStartPar
Turning this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} on (it is off by default) deactivates the use of implicit arguments.

\sphinxAtStartPar
In this case, all arguments of {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
We can reproduce the example above using the {\hyperref[\detokenize{language/extensions/implicit-arguments:coq:flag.Parsing-Explicit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Parsing
Explicit}}}}} flag:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Parsing} \PYG{n}{Explicit}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{id\PYGZsq{}} \PYG{o}{:=} \PYG{n}{id}\PYG{o}{.}
    \PYG{n}{id\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Unset} \PYG{n}{Parsing} \PYG{n}{Explicit}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{id} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{id} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{n}{nat}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{id\PYGZsq{}} \PYG{n}{nat} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{id\PYGZsq{}} \PYG{n}{nat} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Implicit types of variables}
\label{\detokenize{language/extensions/implicit-arguments:implicit-types-of-variables}}
\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{\DUrole{name}{n}}}
or \sphinxcode{\sphinxupquote{\DUrole{name}{m}}} to the type \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}} of natural numbers).
\index{Implicit Type (command)@\spxentry{Implicit Type}\spxextra{command}}\index{Implicit Types (command)@\spxentry{Implicit Types}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:cmd.Implicit-Type}}\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:cmd.Implicit-Types}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Implicit~\DUrole{alternative}{\DUrole{alternative-block}{Type}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Types}}~{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-reserv_list}]{\sphinxcrossref{\DUrole{hole}{reserv\_list}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/implicit-arguments:grammar-token-reserv_list}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-reserv_list}]{\sphinxcrossref{\DUrole{hole}{reserv\_list}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{( {\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-simple_reserv}]{\sphinxcrossref{\DUrole{hole}{simple\_reserv}}}} )}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-simple_reserv}]{\sphinxcrossref{\DUrole{hole}{simple\_reserv}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/implicit-arguments:grammar-token-simple_reserv}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-simple_reserv}]{\sphinxcrossref{\DUrole{hole}{simple\_reserv}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Sets the type of bound
variables starting with {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} (either {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} itself or
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} followed by one or more single quotes, underscore or
digits) to {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} (unless the bound variable is already declared
with an explicit type, in which case, that type will be used).

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\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{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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+kn}{Proof}\PYG{o}{.} \PYG{k}{intros} \PYG{n}{m} \PYG{n}{n}\PYG{o}{.} \PYG{k+kn}{Abort}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{list} \PYG{n}{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{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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}

\PYG{k+kn}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Printing Use Implicit Types (flag)@\spxentry{Printing Use Implicit Types}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:flag.Printing-Use-Implicit-Types}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Use~Implicit~Types}}}}
\sphinxAtStartPar
By default, the type of bound variables is not printed when
the variable name is associated with an implicit type which matches the
actual type of the variable. This feature can be deactivated by
turning this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} off.

\end{fulllineitems}\end{savenotes}



\subsubsection{Implicit generalization}
\label{\detokenize{language/extensions/implicit-arguments:implicit-generalization}}\label{\detokenize{language/extensions/implicit-arguments:id2}}
\index{`\sphinxleftcurlybrace{} \sphinxrightcurlybrace{}@\spxentry{`\sphinxleftcurlybrace{} \sphinxrightcurlybrace{}}}\ignorespaces 
\index{`{[} {]}@\spxentry{`{[} {]}}}\ignorespaces 
\index{`( )@\spxentry{`( )}}\ignorespaces 
\index{`\sphinxleftcurlybrace{}"! \sphinxrightcurlybrace{}@\spxentry{`\sphinxleftcurlybrace{}"! \sphinxrightcurlybrace{}}}\ignorespaces 
\index{`{[}"! {]}@\spxentry{`{[}"! {]}}}\ignorespaces 
\index{`("! )@\spxentry{`("! )}}\ignorespaces \DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/implicit-arguments:grammar-token-generalizing_binder}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-generalizing_binder}]{\sphinxcrossref{\DUrole{hole}{generalizing\_binder}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\`{}( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-typeclass_constraint}]{\sphinxcrossref{\DUrole{hole}{typeclass\_constraint}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\`{}\{ \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-typeclass_constraint}]{\sphinxcrossref{\DUrole{hole}{typeclass\_constraint}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\`{}{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-typeclass_constraint}]{\sphinxcrossref{\DUrole{hole}{typeclass\_constraint}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/implicit-arguments:grammar-token-typeclass_constraint}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-typeclass_constraint}]{\sphinxcrossref{\DUrole{hole}{typeclass\_constraint}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{!}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \} : \DUrole{repeat-wrapper}{\DUrole{repeat}{!}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} : \DUrole{repeat-wrapper}{\DUrole{repeat}{!}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/implicit-arguments:grammar-token-term_generalizing}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/implicit-arguments:grammar-token-term_generalizing}]{\sphinxcrossref{\DUrole{hole}{term\_generalizing}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\`{}\{ {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\`{}( {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Implicit generalization is an automatic elaboration of a statement
with free variables into a closed statement where these variables are
quantified explicitly.  Use the {\hyperref[\detokenize{language/extensions/implicit-arguments:coq:cmd.Generalizable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Generalizable}}}}} command to designate
which variables should be generalized.

\sphinxAtStartPar
It is activated within a binder by prefixing it with `, and for terms by
surrounding it with `\{ \}, or `{[} {]} or `( ).

\sphinxAtStartPar
Terms surrounded by `\{ \} introduce their free variables as maximally
inserted implicit arguments, terms surrounded by `{[} {]} introduce them as
non\sphinxhyphen{}maximally inserted implicit arguments and terms surrounded by `( )
introduce them as explicit arguments.

\sphinxAtStartPar
Generalizing binders always introduce their free variables as
maximally inserted implicit arguments. The binder itself introduces
its argument as usual.

\sphinxAtStartPar
In the following statement, \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{y}} are automatically
generalized, \sphinxcode{\sphinxupquote{A}} is implicit and \sphinxcode{\sphinxupquote{x}}, \sphinxcode{\sphinxupquote{y}} and the anonymous
equality argument are explicit.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Generalizable} \PYG{k+kn}{All} \PYG{k+kn}{Variables}\PYG{o}{.}

\PYG{k+kn}{Definition} \PYG{n}{sym} \PYG{o}{`}\PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{o}{`}\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{o}{:=} \PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}sym} \PYG{n}{p}\PYG{o}{.}
    \PYG{n}{sym} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Print} \PYG{n}{sym}\PYG{o}{.}
    \PYG{n}{sym} \PYG{o}{=} 
    \PYG{k}{fun} \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}{p} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}sym} \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{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x}
    
    \PYG{k+kn}{Arguments} \PYG{n}{sym} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}
\end{sphinxVerbatim}

\sphinxAtStartPar
Dually to normal binders, the name is optional but the type is required:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{forall} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{:\PYGZgt{}} \PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{forall} \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}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

\sphinxAtStartPar
When generalizing a binder whose type is a typeclass, its own class
arguments are omitted from the syntax and are generalized using
automatic names, without instance search. Other arguments are also
generalized unless provided. This produces a fully general statement.
this behaviour may be disabled by prefixing the type with a \sphinxcode{\sphinxupquote{!}} or
by forcing the typeclass name to be an explicit application using
\sphinxcode{\sphinxupquote{@}} (however the later ignores implicit argument information).

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Class} \PYG{n}{Op} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{op} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{.}

\PYG{k+kn}{Class} \PYG{n}{Commutative} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{`}\PYG{o}{(}\PYG{n}{Op} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{commutative} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{op} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=} \PYG{n}{op} \PYG{n}{y} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Instance} \PYG{n}{nat\PYGZus{}op} \PYG{o}{:} \PYG{n}{Op} \PYG{n}{nat} \PYG{o}{:=} \PYG{n}{plus}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}op} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{k+kn}{Implicit}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{forall} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{n}{Commutative} \PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{True}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{Op} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{Commutative} \PYG{n}{A} \PYG{n}{H} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{forall} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{n}{Commutative} \PYG{n}{nat}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{True}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{forall} \PYG{n}{H} \PYG{o}{:} \PYG{n}{Op} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Commutative} \PYG{n}{nat} \PYG{n}{H} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{forall} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{n}{Commutative} \PYG{n}{nat} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{True}\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}{Typeclass} \PYG{n}{does} \PYG{n}{not} \PYG{n}{expect} \PYG{n}{more} \PYG{n}{arguments}

\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{forall} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{o}{!}\PYG{n}{Commutative} \PYG{n}{nat}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{True}\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}{Commutative nat}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Op nat \PYGZhy{}\PYGZgt{} Prop}\PYG{l+s+s2}{\PYGZdq{}}
    \PYG{n}{which} \PYG{n}{should} \PYG{n}{be} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{k+kt}{Prop} \PYG{n}{or} \PYG{k+kt}{Type}\PYG{o}{.}

\PYG{k+kn}{Arguments} \PYG{n}{Commutative} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{forall} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{o}{!}\PYG{n}{Commutative} \PYG{n}{nat}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{True}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{@}\PYG{n}{Commutative} \PYG{n}{nat} \PYG{n}{nat\PYGZus{}op} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{forall} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{o}{@}\PYG{n}{Commutative} \PYG{n}{nat} \PYG{n}{plus}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{True}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{@}\PYG{n}{Commutative} \PYG{n}{nat} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

\sphinxAtStartPar
Multiple binders can be merged using \sphinxcode{\sphinxupquote{,}} as a separator:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{forall} \PYG{o}{`}\PYG{o}{\PYGZob{}}\PYG{n}{Commutative} \PYG{n}{A}\PYG{o}{,} \PYG{n}{Hnat} \PYG{o}{:} \PYG{o}{!}\PYG{n}{Commutative} \PYG{n}{nat}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{True}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{Op} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,}
    \PYG{o}{@}\PYG{n}{Commutative} \PYG{n}{A} \PYG{n}{H} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{@}\PYG{n}{Commutative} \PYG{n}{nat} \PYG{n}{nat\PYGZus{}op} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}
\index{Generalizable (command)@\spxentry{Generalizable}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/implicit-arguments:coq:cmd.Generalizable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Generalizable~\DUrole{alternative}{\DUrole{alternative-block}{\DUrole{alternative}{\DUrole{alternative-block}{Variable}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Variables}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{All~Variables}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{No~Variables}}}}}}
\sphinxAtStartPar
Controls the set of generalizable identifiers.  By default, no variables are
generalizable.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attribute.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Variable}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Variables}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} form allows generalization of only the given \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}s.
Using this command multiple times adds to the allowed identifiers.  The other forms clear
the list of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}s.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{All Variables}}} form generalizes all free variables in
the context that appear 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 variables.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{No Variables}}} form disables implicit generalization entirely.  This is
the default behavior (before any {\hyperref[\detokenize{language/extensions/implicit-arguments:coq:cmd.Generalizable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Generalizable}}}}} command has been entered).

\end{fulllineitems}\end{savenotes}



\subsection{Extended pattern matching}
\label{\detokenize{language/extensions/match:extended-pattern-matching}}\label{\detokenize{language/extensions/match:extendedpatternmatching}}\label{\detokenize{language/extensions/match::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
\sphinxAtStartPar
Cristina Cornes and Hugo Herbelin

\end{description}\end{quote}

\sphinxAtStartPar
This section describes the full form of pattern matching in Coq terms.


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

\paragraph{Multiple and nested pattern matching}
\label{\detokenize{language/extensions/match:multiple-and-nested-pattern-matching}}\label{\detokenize{language/extensions/match:mult-match}}
\sphinxAtStartPar
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\sphinxhyphen{}like languages
(cf. {\hyperref[\detokenize{language/extensions/match:multiple-patterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Multiple patterns}}}} and {\hyperref[\detokenize{language/extensions/match:nested-patterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Nested patterns}}}}).

\sphinxAtStartPar
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/extensions/match:coq:flag.Printing-Matching}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Matching}}}}}).


\paragraph{Pattern\sphinxhyphen{}matching on boolean values: the if expression}
\label{\detokenize{language/extensions/match:pattern-matching-on-boolean-values-the-if-expression}}\label{\detokenize{language/extensions/match:if-then-else}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/match:grammar-token-term_if}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/match:grammar-token-term_if}]{\sphinxcrossref{\DUrole{hole}{term\_if}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{if {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{as {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{?}} return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}\DUrole{notation-sup}{?}} then {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{not} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{n}{bool}\PYG{o}{)} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{b} \PYG{k}{with}
\PYG{o}{|} \PYG{n+nb+bp}{true} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
\PYG{o}{|} \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}

\sphinxAtStartPar
can be alternatively written

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{not} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{n}{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}

\sphinxAtStartPar
More generally, for an inductive type with constructors \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}, the following terms are equal:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{if {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{as {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{?}} return {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}} then {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} else {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{match {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{as {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{?}} return {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}} with | {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\_}\DUrole{notation-sup}{*}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} | {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\_}\DUrole{notation-sup}{*}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}} end}}}

\begin{sphinxadmonition}{note}{Example}

\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}{|} \PYG{k}{left} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
\PYG{o}{|} \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{n}{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{n}{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{n}{bool}
\end{sphinxVerbatim}
\end{sphinxadmonition}

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


\paragraph{Irrefutable patterns: the destructuring let variants}
\label{\detokenize{language/extensions/match:irrefutable-patterns-the-destructuring-let-variants}}\label{\detokenize{language/extensions/match:irrefutable-patterns}}
\sphinxAtStartPar
Pattern\sphinxhyphen{}matching on terms inhabiting inductive type having only one
constructor can be alternatively written using \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{name,builtin,pseudo}{…} \DUrole{keyword}{in} \DUrole{name,builtin,pseudo}{…}}}
constructions. There are two variants of them.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/match:grammar-token-destructuring_let}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/match:grammar-token-destructuring_let}]{\sphinxcrossref{\DUrole{hole}{destructuring\_let}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let ( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} ) \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{as {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{?}} return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let \textquotesingle{} {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}}}\DUrole{notation-sup}{?}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let \textquotesingle{} {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} in {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} return {\hyperref[\detokenize{language/core/basic:grammar-token-term100}]{\sphinxcrossref{\DUrole{hole}{term100}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}

\subparagraph{First destructuring let syntax}
\label{\detokenize{language/extensions/match:first-destructuring-let-syntax}}
\sphinxAtStartPar
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{let ( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} ) := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}}
performs case analysis on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}}}}} whose type must be an
inductive type with exactly one constructor.  The number of variables
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}} must correspond to the number of arguments of this
constructor.  Then, in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}}, these variables are bound to the
arguments of the constructor in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}}}}}.  For instance, the
definition

\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}{|} \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}

\sphinxAtStartPar
can be alternatively written

\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}

\sphinxAtStartPar
Notice that reduction is different from regular \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{name,builtin,pseudo}{…} \DUrole{keyword}{in} \DUrole{name,builtin,pseudo}{…}}}
construction since it happens only if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}}}}} is in constructor form.
Otherwise, the reduction is blocked.

\sphinxAtStartPar
The pretty\sphinxhyphen{}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/extensions/match:controlling-match-pp}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling pretty\sphinxhyphen{}printing of match expressions}}}}).

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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
let (ident₁, …, identₙ) [dep\PYGZus{}ret\PYGZus{}type] := term in term\PYGZsq{}
\end{sphinxVerbatim}

\sphinxAtStartPar
and

\begin{sphinxVerbatim}[commandchars=\\\{\}]
match term [dep\PYGZus{}ret\PYGZus{}type] with
C ident₁ … identₙ =\PYGZgt{} term\PYGZsq{}
end
\end{sphinxVerbatim}


\subparagraph{Second destructuring let syntax}
\label{\detokenize{language/extensions/match:second-destructuring-let-syntax}}
\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
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{name,builtin,pseudo}{’}\DUrole{name}{p} \DUrole{operator}{:=} \DUrole{name}{t} \DUrole{keyword}{in} \DUrole{name}{b}}} allows arbitrary
patterns to do the deconstruction. For example:

\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}{|} \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}

\sphinxAtStartPar
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/extensions/match:controlling-match-pp}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling pretty\sphinxhyphen{}printing of match expressions}}}}).


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


\subparagraph{Printing nested patterns}
\label{\detokenize{language/extensions/match:printing-nested-patterns}}\index{Printing Matching (flag)@\spxentry{Printing Matching}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:flag.Printing-Matching}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Matching}}}}
\sphinxAtStartPar
The Calculus of Inductive Constructions knows pattern matching only
over simple patterns. It is however convenient to re\sphinxhyphen{}factorize nested
pattern matching into a single pattern matching over a nested
pattern.

\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is on (default), Coq’s printer tries to do such
limited re\sphinxhyphen{}factorization.
Turning it off tells Coq to print only simple pattern matching problems
in the same way as the Coq kernel handles them.

\end{fulllineitems}\end{savenotes}



\subparagraph{Factorization of clauses with same right\sphinxhyphen{}hand side}
\label{\detokenize{language/extensions/match:factorization-of-clauses-with-same-right-hand-side}}\index{Printing Factorizable Match Patterns (flag)@\spxentry{Printing Factorizable Match Patterns}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:flag.Printing-Factorizable-Match-Patterns}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Factorizable~Match~Patterns}}}}
\sphinxAtStartPar
When several patterns share the same right\sphinxhyphen{}hand side, it is additionally
possible to share the clauses using disjunctive patterns. Assuming that the
printing matching mode is on, this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (on by default) tells Coq's
printer to try to do this kind of factorization.

\end{fulllineitems}\end{savenotes}



\subparagraph{Use of a default clause}
\label{\detokenize{language/extensions/match:use-of-a-default-clause}}\index{Printing Allow Match Default Clause (flag)@\spxentry{Printing Allow Match Default Clause}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:flag.Printing-Allow-Match-Default-Clause}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Allow~Match~Default~Clause}}}}
\sphinxAtStartPar
When several patterns share the same right\sphinxhyphen{}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 \sphinxcode{\sphinxupquote{\_}} default clause. Assuming that
the printing matching mode and the factorization mode are on, this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (on by
default) tells Coq's printer to use a default clause when relevant.

\end{fulllineitems}\end{savenotes}



\subparagraph{Printing of wildcard patterns}
\label{\detokenize{language/extensions/match:printing-of-wildcard-patterns}}\index{Printing Wildcard (flag)@\spxentry{Printing Wildcard}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:flag.Printing-Wildcard}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Wildcard}}}}
\sphinxAtStartPar
Some variables in a pattern may not occur in the right\sphinxhyphen{}hand side of
the pattern matching clause. When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is on (default), the
variables having no occurrences in the right\sphinxhyphen{}hand side of the
pattern matching clause are just printed using the wildcard symbol
“\_”.

\end{fulllineitems}\end{savenotes}



\subparagraph{Printing of the elimination predicate}
\label{\detokenize{language/extensions/match:printing-of-the-elimination-predicate}}\index{Printing Synth (flag)@\spxentry{Printing Synth}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:flag.Printing-Synth}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Synth}}}}
\sphinxAtStartPar
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 {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is on (default),
the result type is not printed when Coq knows that it can re\sphinxhyphen{}
synthesize it.

\end{fulllineitems}\end{savenotes}



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

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:table.Printing-Let}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Let~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-table}]{\sphinxtermref{\DUrole{xref,std,std-term}{table}}}} 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{language/core/basic:coq:cmd.Add}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add}}}}} and {\hyperref[\detokenize{language/core/basic:coq:cmd.Remove}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove}}}}} commands to update this set.

\end{fulllineitems}\end{savenotes}



\subparagraph{Printing matching on booleans}
\label{\detokenize{language/extensions/match:printing-matching-on-booleans}}
\sphinxAtStartPar
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)@\spxentry{Printing If}\spxextra{table}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:table.Printing-If}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~If~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-table}]{\sphinxtermref{\DUrole{xref,std,std-term}{table}}}} 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{language/core/basic:coq:cmd.Add}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add}}}}} and {\hyperref[\detokenize{language/core/basic:coq:cmd.Remove}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove}}}}}
commands to update this set.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
This example emphasizes what the printing settings offer.

\begin{sphinxadmonition}{note}{Example}

\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}{|} \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{k+kn}{Arguments} \PYG{n}{snd} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}


\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}{|} \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{k+kn}{Arguments} \PYG{n}{snd} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Conventions about unused pattern\sphinxhyphen{}matching variables}
\label{\detokenize{language/extensions/match:conventions-about-unused-pattern-matching-variables}}
\sphinxAtStartPar
Pattern\sphinxhyphen{}matching variables that are not used on the right\sphinxhyphen{}hand side of \sphinxcode{\sphinxupquote{=>}} are
considered the sign of a potential error. For instance, it could
result from an undetected misspelled constant constructor. By default,
a warning is issued in such situations.
\index{Unused variable ‘ident’ catches more than one case (warning)@\spxentry{Unused variable ‘ident’ catches more than one case}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:warn.Unused-variable-_u2018ident_u2019-catches-more-than-one-case}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unused~variable~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~catches~more~than~one~case.}}}}
\sphinxAtStartPar
This indicates that an unused pattern variable {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
occurs in a pattern\sphinxhyphen{}matching clause used to complete at least two
cases of the pattern\sphinxhyphen{}matching problem.

\sphinxAtStartPar
The warning can be deactivated by using a variable name starting
with \sphinxcode{\sphinxupquote{\_}} or by setting \sphinxcode{\sphinxupquote{Set Warnings
"\sphinxhyphen{}unused\sphinxhyphen{}pattern\sphinxhyphen{}matching\sphinxhyphen{}variable"}}.

\sphinxAtStartPar
Here is an example where the warning is activated.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{is\PYGZus{}zero} \PYG{o}{(}\PYG{n}{o} \PYG{o}{:} \PYG{n}{option} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{o} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{Some} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
\PYG{o}{|} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{is\PYGZus{}zero} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\subsubsection{Patterns}
\label{\detokenize{language/extensions/match:patterns}}
\sphinxAtStartPar
The full syntax of \sphinxcode{\sphinxupquote{match}} is presented in {\hyperref[\detokenize{language/core/variants:match-term}]{\sphinxcrossref{\DUrole{std,std-ref}{Definition by cases: match}}}}.
Identifiers in patterns are either constructor names or variables. Any
identifier that is not the constructor of an inductive or co\sphinxhyphen{}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.

\sphinxAtStartPar
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}.

\sphinxAtStartPar
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/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} as {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}} are also accepted. This pattern matches the
same values as {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} does and {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is bound to the matched
value. A pattern of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} | {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{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.

\sphinxAtStartPar
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/extensions/match: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 {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}}, or using the command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Check}}}}}.

\sphinxAtStartPar
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\sphinxhyphen{}hand\sphinxhyphen{}sides of \sphinxcode{\sphinxupquote{=>}} 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.

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{max} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
  \PYG{o}{|} \PYG{n}{S} \PYG{n}{n\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
            \PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \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{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Multiple patterns}
\label{\detokenize{language/extensions/match:multiple-patterns}}\label{\detokenize{language/extensions/match:id1}}
\sphinxAtStartPar
Using multiple patterns in the definition of \sphinxcode{\sphinxupquote{max}} lets us write:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{max} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
    \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
    \PYG{o}{|} \PYG{n}{O}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
    \PYG{o}{|} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}
    \PYG{o}{|} \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}

\sphinxAtStartPar
which will be compiled into the previous form.

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x}\PYG{o}{:}\PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{x} \PYG{k}{return} \PYG{n}{nat} \PYG{k}{with}
                    \PYG{o}{|} \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{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}
         \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
\end{sphinxVerbatim}


\subsubsection{Aliasing subpatterns}
\label{\detokenize{language/extensions/match:aliasing-subpatterns}}
\sphinxAtStartPar
We can also use \sphinxcode{\sphinxupquote{\DUrole{notation}{as {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} to associate a name to a sub\sphinxhyphen{}pattern:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{max} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{O}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
  \PYG{o}{|} \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}{|} \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}


\subsubsection{Nested patterns}
\label{\detokenize{language/extensions/match:nested-patterns}}\label{\detokenize{language/extensions/match:id2}}
\sphinxAtStartPar
Here is now an example of nested patterns:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{even} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
  \PYG{o}{|} \PYG{n}{S} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
  \PYG{o}{|} \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}

\sphinxAtStartPar
This is compiled into:

\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{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
      \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
      \PYG{o}{|} \PYG{n}{S} \PYG{n}{n0} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{n0} \PYG{k}{with}
                \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
                \PYG{o}{|} \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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    
    \PYG{k+kn}{Arguments} \PYG{n}{even} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}
\end{sphinxVerbatim}

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{lef} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{O}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
  \PYG{o}{|} \PYG{n}{x}\PYG{o}{,} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
  \PYG{o}{|} \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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
Another way to write this function is:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{lef} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{O}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
  \PYG{o}{|} \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}{|} \PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
Terms with useless patterns are not accepted by the system. Here is an
example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x}\PYG{o}{:}\PYG{n}{nat} \PYG{o}{=\PYGZgt{}}
              \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
              \PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
              \PYG{o}{|} \PYG{n}{S} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
              \PYG{o}{|} \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}{Pattern} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{is} \PYG{n}{redundant} \PYG{k}{in} \PYG{n}{this} \PYG{n}{clause}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Disjunctive patterns}
\label{\detokenize{language/extensions/match:disjunctive-patterns}}
\sphinxAtStartPar
Multiple patterns that share the same right\sphinxhyphen{}hand\sphinxhyphen{}side can be
factorized using the notation \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}}}}. For
instance, \sphinxcode{\sphinxupquote{\DUrole{name}{max}}} can be rewritten as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{max} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{|} \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}{|} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{p} \PYG{o}{|} \PYG{n}{p}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}}}}.
Here is an example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{filter\PYGZus{}2\PYGZus{}4} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{|} \PYG{l+m+mi}{2} \PYG{k}{as} \PYG{n}{m} \PYG{o}{|} \PYG{l+m+mi}{4} \PYG{k}{as} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
  \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Nested disjunctive patterns are allowed, inside parentheses, with the
notation \sphinxcode{\sphinxupquote{\DUrole{notation}{(\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}})}}}, as in:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{filter\PYGZus{}some\PYGZus{}square\PYGZus{}corners} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{*}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{*}\PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{p} \PYG{k}{with}
  \PYG{o}{|} \PYG{o}{(}\PYG{o}{(}\PYG{l+m+mi}{2} \PYG{k}{as} \PYG{n}{m} \PYG{o}{|} \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}{|} \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}{|} \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}


\subsubsection{About patterns of parametric types}
\label{\detokenize{language/extensions/match:about-patterns-of-parametric-types}}

\paragraph{Parameters in patterns}
\label{\detokenize{language/extensions/match:parameters-in-patterns}}
\sphinxAtStartPar
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:

\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}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{List} \PYG{n}{A}
\PYG{o}{|} \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}

\sphinxAtStartPar
We can check the function \sphinxstyleemphasis{tail}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
     \PYG{o}{|} \PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{n}{nat}
     \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{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
                        \PYG{o}{|} \PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{n}{nat}
                        \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{n}{List} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{n}{nat}
\end{sphinxVerbatim}

\sphinxAtStartPar
When we use parameters in patterns there is an error message:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
     \PYG{o}{|} \PYG{n}{nil} \PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{n}{nat}
     \PYG{o}{|} \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)@\spxentry{Asymmetric Patterns}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:flag.Asymmetric-Patterns}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Asymmetric~Patterns}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (off by default) removes parameters from constructors in patterns:

\end{fulllineitems}\end{savenotes}


\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{n}{nat} \PYG{o}{=\PYGZgt{}}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{o}{\PYGZus{}}
  \PYG{o}{|} \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{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
                        \PYG{o}{|} \PYG{o}{@}\PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{n}{nat}
                        \PYG{o}{|} \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{n}{List} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{n}{nat}

\PYG{k+kn}{Unset} \PYG{n}{Asymmetric} \PYG{n}{Patterns}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Implicit arguments in patterns}
\label{\detokenize{language/extensions/match:implicit-arguments-in-patterns}}
\sphinxAtStartPar
By default, implicit arguments are omitted in patterns. So we write:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{nil} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\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{n}{nat} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
     \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}
     \PYG{o}{|} \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{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
                        \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}
                        \PYG{o}{|} \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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{n}{nat}
\end{sphinxVerbatim}

\sphinxAtStartPar
But the possibility to use all the arguments is given by “\sphinxcode{\sphinxupquote{@}}” implicit
explicitations (as for terms, see {\hyperref[\detokenize{language/extensions/implicit-arguments:explicit-applications}]{\sphinxcrossref{\DUrole{std,std-ref}{Explicit applications}}}}).

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
     \PYG{o}{|} \PYG{o}{@}\PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{o}{@}\PYG{n}{nil} \PYG{n}{nat}
     \PYG{o}{|} \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{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
                        \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}
                        \PYG{o}{|} \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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{n}{nat}
\end{sphinxVerbatim}


\subsubsection{Matching objects of dependent types}
\label{\detokenize{language/extensions/match:matching-objects-of-dependent-types}}\label{\detokenize{language/extensions/match:matching-dependent}}
\sphinxAtStartPar
The previous examples illustrate pattern matching on objects of non\sphinxhyphen{}
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{listn} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{niln} \PYG{o}{:} \PYG{n}{listn} \PYG{l+m+mi}{0}
\PYG{o}{|} \PYG{n}{consn} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{,} \PYG{n}{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}


\subsubsection{Understanding dependencies in patterns}
\label{\detokenize{language/extensions/match:understanding-dependencies-in-patterns}}
\sphinxAtStartPar
We can define the function length over \sphinxcode{\sphinxupquote{\DUrole{name}{listn}}} by:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{length} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{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}

\sphinxAtStartPar
Just for illustrating pattern matching, we can define it by case
analysis:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{length} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{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}{|} \PYG{n}{niln} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{o}{|} \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}

\sphinxAtStartPar
We can understand the meaning of this definition using the same
notions of usual pattern matching.


\subsubsection{When the elimination predicate must be provided}
\label{\detokenize{language/extensions/match:when-the-elimination-predicate-must-be-provided}}

\paragraph{Dependent pattern matching}
\label{\detokenize{language/extensions/match:dependent-pattern-matching}}
\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{concat} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{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{n}{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}{|} \PYG{n}{niln} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
  \PYG{o}{|} \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}

\sphinxAtStartPar
The elimination predicate is \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{n}\DUrole{operator}{:}\DUrole{name}{nat}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{l}\DUrole{operator}{:}\DUrole{name}{listn} \DUrole{name}{n}\DUrole{operator}{)} \DUrole{operator}{=>} \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{name,builtin,pseudo}{…} \DUrole{name}{qr} \DUrole{name}{t1} \DUrole{name,builtin,pseudo}{…} \DUrole{name}{ts}\DUrole{operator}{)}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{q1}\DUrole{operator}{,} \DUrole{name,builtin,pseudo}{…}\DUrole{operator}{,} \DUrole{name}{qr}}}
are parameters, the elimination predicate should be of the form \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{y1} \DUrole{name,builtin,pseudo}{…} \DUrole{name}{ys} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{operator}{(}\DUrole{name}{I} \DUrole{name}{q1} \DUrole{name,builtin,pseudo}{…} \DUrole{name}{qr} \DUrole{name}{y1} \DUrole{name,builtin,pseudo}{…} \DUrole{name}{ys} \DUrole{operator}{)} \DUrole{operator}{=>} \DUrole{name}{Q}}}.

\sphinxAtStartPar
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{\_}}.


\paragraph{Multiple dependent pattern matching}
\label{\detokenize{language/extensions/match:multiple-dependent-pattern-matching}}
\sphinxAtStartPar
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 with an \sphinxcode{\sphinxupquote{as}} clause and an \sphinxcode{\sphinxupquote{in}} clause in order to introduce
a dependent product.

\sphinxAtStartPar
For example, an equivalent definition for \sphinxcode{\sphinxupquote{\DUrole{name}{concat}}} (even though the
matching on the second term is trivial) would have been:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{concat} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{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{n}{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}{|} \PYG{n}{niln}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}
  \PYG{o}{|} \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}

\sphinxAtStartPar
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

\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}{|} \PYG{n}{niln}\PYG{o}{,} \PYG{n}{b0} \PYG{o}{=\PYGZgt{}} \PYG{n}{tt}
 \PYG{o}{|} \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}

\sphinxAtStartPar
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}{)}}}.


\paragraph{Patterns in \sphinxstyleliteralintitle{\sphinxupquote{in}}}
\label{\detokenize{language/extensions/match:patterns-in-in}}\label{\detokenize{language/extensions/match:match-in-patterns}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
To be concrete: the \sphinxcode{\sphinxupquote{tail}} function can be written:

\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}{|} \PYG{n}{niln} \PYG{o}{=\PYGZgt{}} \PYG{n}{False\PYGZus{}rect} \PYG{n}{unit}
  \PYG{o}{|} \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}

\sphinxAtStartPar
and \sphinxcode{\sphinxupquote{\DUrole{name}{tail} \DUrole{name}{n} \DUrole{name}{v}}} will be subterm of \sphinxcode{\sphinxupquote{\DUrole{name}{v}}}.


\subsubsection{Using pattern matching to write proofs}
\label{\detokenize{language/extensions/match:using-pattern-matching-to-write-proofs}}
\sphinxAtStartPar
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}}}}}.

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{buildlist} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{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}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{niln}
  \PYG{o}{|} \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}

\sphinxAtStartPar
We can also use multiple patterns. Consider the following definition
of the predicate less\sphinxhyphen{}equal \sphinxcode{\sphinxupquote{\DUrole{name}{Le}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{LE} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{o}{|} \PYG{n}{LEO} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{,} \PYG{n}{LE} \PYG{l+m+mi}{0} \PYG{n}{n}
  \PYG{o}{|} \PYG{n}{LES} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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}

\sphinxAtStartPar
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{name}{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}{)}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{dec} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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}{|} \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}{|} \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}{|} \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}{|} \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}{|} \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}

\sphinxAtStartPar
In the example of \sphinxcode{\sphinxupquote{\DUrole{name}{dec}}}, the first match is dependent while the second
is not.

\sphinxAtStartPar
The user can also use match in combination with the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}
to build incomplete proofs beginning with a \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} construction.


\subsubsection{Pattern\sphinxhyphen{}matching on inductive objects involving local definitions}
\label{\detokenize{language/extensions/match:pattern-matching-on-inductive-objects-involving-local-definitions}}
\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{list} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list} \PYG{l+m+mi}{0}
\PYG{o}{|} \PYG{n}{cons} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{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{n}{list} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
In the next example, the local definition is not caught.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{length} \PYG{n}{n} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{n}{list} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{o}{|} \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}

\sphinxAtStartPar
But in this example, it is.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{length\PYGZsq{}} \PYG{n}{n} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{n}{list} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{o}{|} \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:}
\sphinxAtStartPar
For a given matching clause, either none of the local
definitions or all of them can be caught.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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:}
\sphinxAtStartPar
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}


\subsubsection{Pattern\sphinxhyphen{}matching and coercions}
\label{\detokenize{language/extensions/match:pattern-matching-and-coercions}}
\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{I} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
  \PYG{o}{|} \PYG{n}{C1} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{I}
  \PYG{o}{|} \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{n}{nat} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{I}\PYG{o}{.}
\end{sphinxVerbatim}

\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}{|} \PYG{n}{C2} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
                \PYG{o}{|} \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}{|} \PYG{n}{C1} \PYG{o}{\PYGZus{}} \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
                 \PYG{k}{end}
         \PYG{o}{:} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{When does the expansion strategy fail?}
\label{\detokenize{language/extensions/match:when-does-the-expansion-strategy-fail}}
\sphinxAtStartPar
The strategy works very like in ML languages when treating patterns of
non\sphinxhyphen{}dependent types. But there are new cases of failure that are due to
the presence of dependencies.

\sphinxAtStartPar
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\sphinxhyphen{}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) => e1}} and
\sphinxcode{\sphinxupquote{(cons n \_ x) => e2}} instead of \sphinxcode{\sphinxupquote{(cons n O x) => e1}} and
\sphinxcode{\sphinxupquote{(cons n' \_ x') => e2}}. This helps to maintain certain name correspondence between the
generated expression and the original.

\sphinxAtStartPar
Here is a summary of the error messages corresponding to each
situation:
\index{The constructor ‘ident’ expects ‘natural’ arguments (error)@\spxentry{The constructor ‘ident’ expects ‘natural’ arguments}\spxextra{error}}\index{The variable ident is bound several times in pattern term (error)@\spxentry{The variable ident is bound several times in pattern term}\spxextra{error}}\index{Found a constructor of inductive type term while a constructor of term is expected (error)@\spxentry{Found a constructor of inductive type term while a constructor of term is expected}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:exn.The-constructor-_u2018ident_u2019-expects-_u2018natural_u2019-arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~constructor~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~expects~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~arguments.}}}}\phantomsection\label{\detokenize{language/extensions/match:coq:exn.The-variable-ident-is-bound-several-times-in-pattern-term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~variable~ident~is~bound~several~times~in~pattern~term}}}}\phantomsection\label{\detokenize{language/extensions/match:coq:exn.Found-a-constructor-of-inductive-type-term-while-a-constructor-of-term-is-expected}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Found~a~constructor~of~inductive~type~term~while~a~constructor~of~term~is~expected}}}}
\sphinxAtStartPar
Patterns are incorrect (because constructors are not applied to the correct number of
arguments, because they are not linear or they are wrongly typed).

\end{fulllineitems}\end{savenotes}

\index{Non exhaustive pattern matching (error)@\spxentry{Non exhaustive pattern matching}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:exn.Non-exhaustive-pattern-matching}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Non~exhaustive~pattern~matching.}}}}
\sphinxAtStartPar
The pattern matching is not exhaustive.

\end{fulllineitems}\end{savenotes}

\index{The elimination predicate term should be of arity ‘natural’ (for non dependent case) or ‘natural’ (for dependent case) (error)@\spxentry{The elimination predicate term should be of arity ‘natural’ (for non dependent case) or ‘natural’ (for dependent case)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match:coq:exn.The-elimination-predicate-term-should-be-of-arity-_u2018natural_u2019-(for-non-dependent-case)-or-_u2018natural_u2019-(for-dependent-case)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~elimination~predicate~term~should~be~of~arity~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~(for~non~dependent~case)~or~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~(for~dependent~case).}}}}
\sphinxAtStartPar
The elimination predicate provided to match has not the expected arity.

\end{fulllineitems}\end{savenotes}

\index{Unable to infer a match predicate (error)@\spxentry{Unable to infer a match predicate}\spxextra{error}}\index{Either there is a type incompatibility or the problem involves dependencies (error)@\spxentry{Either there is a type incompatibility or the problem involves dependencies}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/match: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{language/extensions/match: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.}}}}
\sphinxAtStartPar
There is a type mismatch between the different branches. The user should
provide an elimination predicate.

\end{fulllineitems}\end{savenotes}



\subsection{Syntax extensions and notation scopes}
\label{\detokenize{user-extensions/syntax-extensions:syntax-extensions-and-notation-scopes}}\label{\detokenize{user-extensions/syntax-extensions:id1}}\label{\detokenize{user-extensions/syntax-extensions::doc}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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, Coq offers a notion
of {\hyperref[\detokenize{user-extensions/syntax-extensions:scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{notation 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}}}}}.


\subsubsection{Notations}
\label{\detokenize{user-extensions/syntax-extensions:notations}}\label{\detokenize{user-extensions/syntax-extensions:id2}}

\paragraph{Basic notations}
\label{\detokenize{user-extensions/syntax-extensions:basic-notations}}\index{Notation (command)@\spxentry{Notation}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Notation~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~)}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Defines a \sphinxstyleemphasis{notation}, an alternate syntax for entering or displaying
a specific term or term pattern.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which limits its effect to the
current module.
If the command is inside a section, its effect is limited to the section.

\sphinxAtStartPar
Specifying {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_name}}}}} associates the notation with that scope.  Otherwise
it is a \sphinxstyleemphasis{lonely notation}, that is, not associated with a scope.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
For example, the following definition permits using the infix expression \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{B}}}
to represent \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{and} \DUrole{name}{A} \DUrole{name}{B}\DUrole{operator}{)}}}:

\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}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{literal,string,double}{"A /\textbackslash{} B"}}} is a \sphinxstyleemphasis{notation}, which tells how to represent the abbreviated term
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{and} \DUrole{name}{A} \DUrole{name}{B}\DUrole{operator}{)}}}.

\sphinxAtStartPar
Notations must be in 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 consists of \sphinxstyleemphasis{tokens} separated by
spaces. Tokens which are identifiers (such as \sphinxcode{\sphinxupquote{A}}, \sphinxcode{\sphinxupquote{x0'}}, etc.) are the \sphinxstyleemphasis{parameters}
of the notation. Each of them must occur at least once in the abbreviated term. The
other elements of the string (such as \sphinxcode{\sphinxupquote{/\textbackslash{}}}) are the \sphinxstyleemphasis{symbols}.

\sphinxAtStartPar
Identifiers enclosed in single quotes are treated as symbols and thus
lose their role of parameters. In the same vein, every symbol of at
least 3 characters and starting with a simple quote must be quoted
(then it starts with two single quotes). Here is an example.

\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}{c1} \PYG{o}{/\PYGZbs{}} \PYG{n}{c2} \PYG{o}{\PYGZbs{}/} \PYG{o}{\PYGZti{}} \PYG{n}{c1} \PYG{o}{/\PYGZbs{}} \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{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
A notation binds a syntactic expression to a term. Unless the parser
and pretty\sphinxhyphen{}printer of Coq already know how to deal with the syntactic
expression (such as through {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Reserved-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Reserved Notation}}}}} or for notations
that contain only literals), explicit precedences and
associativity rules have to be given.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The right\sphinxhyphen{}hand side of a notation is interpreted at the time the notation is
given. In particular, disambiguation of constants, {\hyperref[\detokenize{language/extensions/implicit-arguments:implicitarguments}]{\sphinxcrossref{\DUrole{std,std-ref}{implicit arguments}}}} and other notations are resolved at the
time of the declaration of the notation. The right\sphinxhyphen{}hand side is
currently typed only at use time but this may change in the future.
\end{sphinxadmonition}


\paragraph{Precedences and associativity}
\label{\detokenize{user-extensions/syntax-extensions:precedences-and-associativity}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
Consider for example the new notation

\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}[20]\sphinxAtStartFootnote
which are the levels effectively chosen in the current
implementation of Coq
%
\end{footnote}.

\sphinxAtStartPar
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\sphinxhyphen{}formed and that parentheses are mandatory (this is a “no
associativity”) %
\begin{footnote}[21]\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 for
the associativity of disjunction and conjunction, so let us apply
right associativity (which is the choice of Coq).

\sphinxAtStartPar
Precedence levels and associativity rules of notations are specified with a list of
parenthesized \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}}}s.  Here is how the previous examples refine:

\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}

\sphinxAtStartPar
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.


\paragraph{Complex notations}
\label{\detokenize{user-extensions/syntax-extensions:complex-notations}}
\sphinxAtStartPar
Notations can be made from arbitrarily complex symbols. One can for
instance define prefix notations.

\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}

\sphinxAtStartPar
One can also define notations for incomplete terms, with the hole
expected to be inferred during type checking.

\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}

\sphinxAtStartPar
One can define \sphinxstyleemphasis{closed} notations whose both sides are symbols. In this case,
the default precedence level for the inner sub\sphinxhyphen{}expression is 200, and the default
level for the notation itself is 0.

\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}

\sphinxAtStartPar
One can also define notations for binders.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x : A | 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}

\sphinxAtStartPar
In the last case though, there is a conflict with the notation for
type casts. The notation for type casts, as shown by the command {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Grammar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print
Grammar}}}}} \sphinxcode{\sphinxupquote{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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x : A | 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}

\sphinxAtStartPar
More generally, it is required that notations are explicitly factorized on the
left. See the next section for more about factorization.


\paragraph{Simple factorization rules}
\label{\detokenize{user-extensions/syntax-extensions:simple-factorization-rules}}
\sphinxAtStartPar
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.

\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{n}{Fail} \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}{60}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{Fail} \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{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Warning}\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{n}{was} \PYG{n}{already} \PYG{n}{defined} \PYG{k}{with} \PYG{n}{a} \PYG{n}{different} \PYG{n}{format}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{notation}\PYG{o}{\PYGZhy{}}\PYG{n}{incompatible}\PYG{o}{\PYGZhy{}}\PYG{n}{format}\PYG{o}{,}\PYG{n}{parsing}\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}{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{o}{,} \PYG{n}{constr} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\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}

\sphinxAtStartPar
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}}}}.


\paragraph{Use of notations for printing}
\label{\detokenize{user-extensions/syntax-extensions:use-of-notations-for-printing}}
\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
However, printing, especially pretty\sphinxhyphen{}printing, also requires some
care. We may want specific indentations, line breaks, alignment if on
several lines, etc. For pretty\sphinxhyphen{}printing, Coq relies on OCaml
formatting library, which provides indentation and automatic line
breaks depending on page width by means of \sphinxstyleemphasis{formatting boxes}.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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 next to the
curly braces.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{}\PYGZob{}  x : A | 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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{sig} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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{n}{nat} \PYG{o}{|} \PYG{n}{x} \PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

\sphinxAtStartPar
The second, more powerful control on printing is by using \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}}}s. Here is an example

\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}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{43}\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}{\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{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}{Error}\PYG{o}{:} \PYG{n}{The} \PYG{n}{reference} \PYG{n}{IF\PYGZus{}then\PYGZus{}else} \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}

\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}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{9}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{21}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \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{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}{Error}\PYG{o}{:} \PYG{n}{The} \PYG{n}{reference} \PYG{n}{IF\PYGZus{}then\PYGZus{}else} \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}

\sphinxAtStartPar
A \sphinxstyleemphasis{format} is an extension of the string denoting the notation with
the possible following elements delimited by single quotes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
tokens of the form \sphinxcode{\sphinxupquote{'/ '}} are translated into breaking points.  If
there is a line break, indents the number of spaces appearing after the
“\sphinxcode{\sphinxupquote{/}}” (no indentation in the example)

\item {} 
\sphinxAtStartPar
tokens of the form \sphinxcode{\sphinxupquote{'//'}} force writing on a new line

\item {} 
\sphinxAtStartPar
well\sphinxhyphen{}bracketed pairs of tokens of the form \sphinxcode{\sphinxupquote{'{[} '}} and \sphinxcode{\sphinxupquote{'{]}'}} are
translated into printing boxes; if there is a line break, an extra
indentation of the number of spaces after the “\sphinxcode{\sphinxupquote{{[}}}” is applied

\item {} 
\sphinxAtStartPar
well\sphinxhyphen{}bracketed pairs of tokens of the form \sphinxcode{\sphinxupquote{'{[}hv '}} and \sphinxcode{\sphinxupquote{'{]}'}} are
translated into horizontal\sphinxhyphen{}or\sphinxhyphen{}else\sphinxhyphen{}vertical printing boxes; if the
content of the box does not fit on a single line, then every breaking
point forces a new line and an extra indentation of the number of
spaces after the “\sphinxcode{\sphinxupquote{{[}hv}}” is applied at the beginning of each new line

\item {} 
\sphinxAtStartPar
well\sphinxhyphen{}bracketed pairs of tokens of the form \sphinxcode{\sphinxupquote{'{[}v '}} and \sphinxcode{\sphinxupquote{'{]}'}} are
translated into vertical printing boxes; every breaking point forces a
new line, even if the line is large enough to display the whole content
of the box, and an extra indentation of the number of spaces
after the “\sphinxcode{\sphinxupquote{{[}v}}” is applied at the beginning of each new line (3 spaces
in the example)

\item {} 
\sphinxAtStartPar
extra spaces in other tokens are preserved in the output

\end{itemize}

\sphinxAtStartPar
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:}
\sphinxAtStartPar
The default for a notation is to be used both for parsing and
printing. It is possible to declare a notation only for parsing by
adding the option \sphinxcode{\sphinxupquote{only parsing}} to the list of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}}}s of {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}}. Symmetrically, the
\sphinxcode{\sphinxupquote{only printing}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}}} can be used to declare that
a notation should only be used for printing.

\sphinxAtStartPar
If a notation to be used both for parsing and printing is
overridden, both the parsing and printing are invalided, even if the
overriding rule is only parsing.

\sphinxAtStartPar
If a given notation string occurs only in \sphinxcode{\sphinxupquote{only printing}} rules,
the parser is not modified at all.

\sphinxAtStartPar
To a given notation string and scope can be attached at most one
notation with both parsing and printing or with only
parsing. Contrastingly, an arbitrary number of \sphinxcode{\sphinxupquote{only printing}}
notations differing in their right\sphinxhyphen{}hand sides but only a unique
right\sphinxhyphen{}hand side can be attached to a given string and
scope. Obviously, expressions printed by means of such extra
printing rules will not be reparsed to the same form.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
When several notations can be used to print a given term, the
notations which capture the largest subterm of the term are used
preferentially. Here is an example:

\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}{lt} \PYG{n}{x} \PYG{n}{y} \PYG{o}{/\PYGZbs{}} \PYG{n}{lt} \PYG{n}{y} \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}{.}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
When several notations match the same subterm, or incomparable
subterms of the term to print, the notation declared most recently
is selected. Moreover, reimporting a library or module declares the
notations of this library or module again. If the notation is in a
scope (see {\hyperref[\detokenize{user-extensions/syntax-extensions:scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Notation scopes}}}}), either the scope has to be opened or a
delimiter has to exist in the scope for the notation to be usable.
\end{sphinxadmonition}


\paragraph{The Infix command}
\label{\detokenize{user-extensions/syntax-extensions:the-infix-command}}
\sphinxAtStartPar
The {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Infix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Infix}}}}} command is a shortcut for declaring notations for infix
symbols.
\index{Infix (command)@\spxentry{Infix}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Infix}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Infix~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~)}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This command is equivalent to
\begin{quote}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Notation "x {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} y" := ({\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} x y) \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}\DUrole{notation-sup}{?}}}}}
\end{quote}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} are fresh names and omitting the quotes around \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}.
Here is an example:

\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}\end{savenotes}



\paragraph{Reserving notations}
\label{\detokenize{user-extensions/syntax-extensions:reserving-notations}}\label{\detokenize{user-extensions/syntax-extensions:reservingnotations}}\index{Reserved Notation (command)@\spxentry{Reserved Notation}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Reserved-Notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reserved~Notation~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~)}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
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, this command declares a parsing rule ({\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}) in advance
without giving its interpretation. Here is an example from the initial
state of Coq.

\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}

\sphinxAtStartPar
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:}
\sphinxAtStartPar
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}
\index{Reserved Infix (command)@\spxentry{Reserved Infix}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Reserved-Infix}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reserved~Infix~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~)}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This command declares an infix parsing rule without giving its
interpretation.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
When a format is attached to a reserved notation (with the \sphinxcode{\sphinxupquote{format}}
{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{syntax\_modifier}}}}}), it is used by
default by all subsequent interpretations of the corresponding
notation. Individual interpretations can override the format.

\end{fulllineitems}\end{savenotes}



\paragraph{Simultaneous definition of terms and notations}
\label{\detokenize{user-extensions/syntax-extensions:simultaneous-definition-of-terms-and-notations}}
\sphinxAtStartPar
Thanks to reserved notations, inductive, co\sphinxhyphen{}inductive, record, recursive and
corecursive definitions can use customized notations. To do this, insert
a {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notations}}}}} 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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notation}]{\sphinxcrossref{\DUrole{hole}{decl\_notation}}}}}}} for inductive,
co\sphinxhyphen{}inductive, recursive and corecursive definitions and in {\hyperref[\detokenize{language/core/records:record-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Record types}}}}
for records. Note that only syntax modifiers that do not require adding or
changing a parsing rule are accepted.
\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notations}]{\sphinxcrossref{\DUrole{hole}{decl\_notations}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{where {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notation}]{\sphinxcrossref{\DUrole{hole}{decl\_notation}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{and {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notation}]{\sphinxcrossref{\DUrole{hole}{decl\_notation}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notation}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notation}]{\sphinxcrossref{\DUrole{hole}{decl\_notation}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}

\sphinxAtStartPar
Here are examples:

\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}

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
    \PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
    \PYG{o}{|} \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}


\paragraph{Displaying information about notations}
\label{\detokenize{user-extensions/syntax-extensions:displaying-information-about-notations}}\index{Printing Notations (flag)@\spxentry{Printing Notations}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls whether to use notations for printing terms wherever possible.
Default is on.

\end{fulllineitems}\end{savenotes}

\index{Printing Raw Literals (flag)@\spxentry{Printing Raw Literals}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:flag.Printing-Raw-Literals}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Raw~Literals}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls whether to use string and number notations for printing terms
wherever possible (see {\hyperref[\detokenize{user-extensions/syntax-extensions:string-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{String notations}}}}).
Default is off.

\end{fulllineitems}\end{savenotes}

\index{Printing Parentheses (flag)@\spxentry{Printing Parentheses}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:flag.Printing-Parentheses}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Parentheses}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is on, parentheses are printed even if
implied by associativity and precedence. Default is off.

\end{fulllineitems}\end{savenotes}



\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} to disable other elements in addition to notations.


\index{Print Grammar (command)@\spxentry{Print Grammar}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Grammar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Grammar~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Shows the grammar for the nonterminal {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, which must be one of the following:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{constr}} \sphinxhyphen{} for {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}s

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{pattern}} \sphinxhyphen{} for {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}s

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{tactic}} \sphinxhyphen{} for currently\sphinxhyphen{}defined tactic notations, {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic}}}}}s and tacticals
(corresponding to {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} in the documentation).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{vernac}} \sphinxhyphen{} for {\hyperref[\detokenize{language/core/basic:grammar-token-command}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{command}}}}}s

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ltac2}} \sphinxhyphen{} for Ltac2 notations (corresponding to {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr}}}}})

\end{itemize}

\sphinxAtStartPar
This command doesn't display all nonterminals of the grammar.  For example,
productions shown by \sphinxcode{\sphinxupquote{Print Grammar tactic}} refer to nonterminals \sphinxcode{\sphinxupquote{tactic\_then\_locality}}
and \sphinxcode{\sphinxupquote{for\_each\_goal}} which are not shown and can't be printed.

\sphinxAtStartPar
Most of the grammar in the documentation was updated in 8.12 to make it accurate and
readable.  This was done using a new developer tool that extracts the grammar from the
source code, edits it and inserts it into the documentation files.  While the
edited grammar is equivalent to the original, for readability some nonterminals
have been renamed and others have been eliminated by substituting the nonterminal
definition where the nonterminal was referenced.  This command shows the original grammar,
so it won't exactly match the documentation.

\sphinxAtStartPar
The Coq parser is based on Camlp5.  The documentation for
\sphinxhref{http://camlp5.github.io/doc/htmlc/grammars.html}{Extensible grammars}%
\begin{footnote}[14]\sphinxAtStartFootnote
\sphinxnolinkurl{http://camlp5.github.io/doc/htmlc/grammars.html}
%
\end{footnote} is the
most relevant but it assumes considerable knowledge.  Here are the essentials:

\sphinxAtStartPar
Productions can contain the following elements:
\begin{itemize}
\item {} 
\sphinxAtStartPar
nonterminal names \sphinxhyphen{} identifiers in the form \sphinxcode{\sphinxupquote{{[}a\sphinxhyphen{}zA\sphinxhyphen{}Z0\sphinxhyphen{}9\_{]}*}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{"…"}} \sphinxhyphen{} a literal string that becomes a keyword and cannot be used as an {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.
The string doesn't have to be a valid identifier; frequently the string will contain only
punctuation characters.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{IDENT "…"}} \sphinxhyphen{} a literal string that has the form of an {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{OPT element}} \sphinxhyphen{} optionally include \sphinxcode{\sphinxupquote{element}} (e.g. a nonterminal, IDENT "…" or "…")

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{LIST1 element}} \sphinxhyphen{} a list of one or more \sphinxcode{\sphinxupquote{element}}s

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{LIST0 element}} \sphinxhyphen{} an optional list of \sphinxcode{\sphinxupquote{element}}s

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{LIST1 element SEP sep}} \sphinxhyphen{} a list of \sphinxcode{\sphinxupquote{element}}s separated by \sphinxcode{\sphinxupquote{sep}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{LIST0 element SEP sep}} \sphinxhyphen{} an optional list of \sphinxcode{\sphinxupquote{element}}s separated by \sphinxcode{\sphinxupquote{sep}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{{[} elements1 | elements2 | … {]}}} \sphinxhyphen{} alternatives (either \sphinxcode{\sphinxupquote{elements1}} or \sphinxcode{\sphinxupquote{elements2}} or …)

\end{itemize}

\sphinxAtStartPar
Nonterminals can have multiple \sphinxstylestrong{levels} to specify precedence and associativity
of its productions.  This feature of grammars makes it simple to parse input
such as \sphinxcode{\sphinxupquote{1+2*3}} in the usual way as \sphinxcode{\sphinxupquote{1+(2*3)}}.  However, most nonterminals have a single level.

\sphinxAtStartPar
For example, this output from \sphinxcode{\sphinxupquote{Print Grammar tactic}} shows the first 3 levels for
\sphinxcode{\sphinxupquote{ltac\_expr}}, designated as "5", "4" and "3".  Level 3 is right\sphinxhyphen{}associative,
which applies to the productions within it, such as the \sphinxcode{\sphinxupquote{try}} construct:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Entry ltac\PYGZus{}expr is
[ \PYGZdq{}5\PYGZdq{} RIGHTA
  [ binder\PYGZus{}tactic ]
| \PYGZdq{}4\PYGZdq{} LEFTA
  [ SELF; \PYGZdq{};\PYGZdq{}; binder\PYGZus{}tactic
  | SELF; \PYGZdq{};\PYGZdq{}; SELF
  | SELF; \PYGZdq{};\PYGZdq{}; tactic\PYGZus{}then\PYGZus{}locality; for\PYGZus{}each\PYGZus{}goal; \PYGZdq{}]\PYGZdq{} ]
| \PYGZdq{}3\PYGZdq{} RIGHTA
  [ IDENT \PYGZdq{}try\PYGZdq{}; SELF
  :
\end{sphinxVerbatim}

\sphinxAtStartPar
The interpretation of \sphinxcode{\sphinxupquote{SELF}} depends on its position in the production and the
associativity of the level:
\begin{itemize}
\item {} 
\sphinxAtStartPar
At the beginning of a production, \sphinxcode{\sphinxupquote{SELF}} means the next level.  In the
fragment shown above, the next level for \sphinxcode{\sphinxupquote{try}} is "2".  (This is defined by the order
of appearance in the grammar or output; the levels could just as well be
named "foo" and "bar".)

\item {} 
\sphinxAtStartPar
In the middle of a production, \sphinxcode{\sphinxupquote{SELF}} means the top level ("5" in the fragment)

\item {} 
\sphinxAtStartPar
At the end of a production, \sphinxcode{\sphinxupquote{SELF}} means the next level within
\sphinxcode{\sphinxupquote{LEFTA}} levels and the current level within \sphinxcode{\sphinxupquote{RIGHTA}} levels.

\end{itemize}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{NEXT}} always means the next level. \sphinxcode{\sphinxupquote{nonterminal LEVEL "…"}} is a reference to the specified level
for \sphinxcode{\sphinxupquote{nonterminal}}.

\sphinxAtStartPar
\sphinxhref{http://camlp5.github.io/doc/htmlc/grammars.html\#b:Associativity}{Associativity}%
\begin{footnote}[15]\sphinxAtStartFootnote
\sphinxnolinkurl{http://camlp5.github.io/doc/htmlc/grammars.html\#b:Associativity}
%
\end{footnote}
explains \sphinxcode{\sphinxupquote{SELF}} and \sphinxcode{\sphinxupquote{NEXT}} in somewhat more detail.

\sphinxAtStartPar
The output for \sphinxcode{\sphinxupquote{Print Grammar constr}} includes {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} definitions,
which are dynamically added to the grammar at run time.
For example, in the definition for \sphinxcode{\sphinxupquote{term}}, the production on the second line shown
here is defined by a {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Reserved-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Reserved Notation}}}}} command in \sphinxcode{\sphinxupquote{Notations.v}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
| \PYGZdq{}50\PYGZdq{} LEFTA
  [ SELF; \PYGZdq{}||\PYGZdq{}; NEXT
\end{sphinxVerbatim}

\sphinxAtStartPar
Similarly, \sphinxcode{\sphinxupquote{Print Grammar tactic}} includes {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Tactic-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Tactic Notation}}}}}s, such as {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.dintuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dintuition}}}}}.

\sphinxAtStartPar
The file
\sphinxhref{http://github.com/coq/coq/blob/master/doc/tools/docgram/fullGrammar}{doc/tools/docgram/fullGrammar}%
\begin{footnote}[16]\sphinxAtStartFootnote
\sphinxnolinkurl{http://github.com/coq/coq/blob/master/doc/tools/docgram/fullGrammar}
%
\end{footnote}
in the source tree extracts the full grammar for
Coq (not including notations and tactic notations defined in \sphinxcode{\sphinxupquote{*.v}} files nor some optionally\sphinxhyphen{}loaded plugins)
in a single file with minor changes to handle nonterminals using multiple levels (described in
\sphinxhref{http://github.com/coq/coq/blob/master/doc/tools/docgram/README.md}{doc/tools/docgram/README.md}%
\begin{footnote}[17]\sphinxAtStartFootnote
\sphinxnolinkurl{http://github.com/coq/coq/blob/master/doc/tools/docgram/README.md}
%
\end{footnote}).
This is complete and much easier to read than the grammar source files.
\sphinxhref{http://github.com/coq/coq/blob/master/doc/tools/docgram/orderedGrammar}{doc/tools/docgram/orderedGrammar}%
\begin{footnote}[18]\sphinxAtStartFootnote
\sphinxnolinkurl{http://github.com/coq/coq/blob/master/doc/tools/docgram/orderedGrammar}
%
\end{footnote}
has the edited grammar that's used in the documentation.

\sphinxAtStartPar
Developer documentation for parsing is in
\sphinxhref{http://github.com/coq/coq/blob/master/dev/doc/parsing.md}{dev/doc/parsing.md}%
\begin{footnote}[19]\sphinxAtStartFootnote
\sphinxnolinkurl{http://github.com/coq/coq/blob/master/dev/doc/parsing.md}
%
\end{footnote}.

\end{fulllineitems}\end{savenotes}



\paragraph{Locating notations}
\label{\detokenize{user-extensions/syntax-extensions:locating-notations}}\label{\detokenize{user-extensions/syntax-extensions:id5}}
\sphinxAtStartPar
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.

\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{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}{type\PYGZus{}scope} \PYG{o}{(}\PYG{n}{default} \PYG{n}{interpretation}\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{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{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{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}{type\PYGZus{}scope} \PYG{o}{(}\PYG{n}{default} \PYG{n}{interpretation}\PYG{o}{)}
\end{sphinxVerbatim}


\paragraph{Inheritance of the properties of arguments of constants bound to a notation}
\label{\detokenize{user-extensions/syntax-extensions:inheritance-of-the-properties-of-arguments-of-constants-bound-to-a-notation}}
\sphinxAtStartPar
If the right\sphinxhyphen{}hand side of a notation is a partially applied constant,
the notation inherits the implicit arguments (see
{\hyperref[\detokenize{language/extensions/implicit-arguments:implicitarguments}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit arguments}}}}) and notation scopes (see
{\hyperref[\detokenize{user-extensions/syntax-extensions:scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Notation scopes}}}}) of the constant. For instance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Record} \PYG{n}{R} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{n}{dom} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{;} \PYG{n}{op} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{dom}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsh{} x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{o}{@}\PYG{n}{op} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{8}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k}{fun} \PYG{n}{x}\PYG{o}{:}\PYG{n}{R} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZsh{}} \PYG{n}{x} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{R} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZsh{}} \PYG{n}{x} \PYG{l+m+mi}{3}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{R}\PYG{o}{,} \PYG{n}{dom} \PYG{n}{x}
\end{sphinxVerbatim}

\sphinxAtStartPar
As an exception, if the right\sphinxhyphen{}hand side is just of the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{@{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, this conventionally stops the inheritance of implicit
arguments (but not of notation scopes).


\paragraph{Notations and binders}
\label{\detokenize{user-extensions/syntax-extensions:notations-and-binders}}\label{\detokenize{user-extensions/syntax-extensions:id6}}
\sphinxAtStartPar
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}}}}.


\subparagraph{Binders bound in the notation and parsed as identifiers}
\label{\detokenize{user-extensions/syntax-extensions:binders-bound-in-the-notation-and-parsed-as-identifiers}}
\sphinxAtStartPar
Here is the basic example of a notation using a binder:

\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}{name}\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}

\sphinxAtStartPar
The binding variables in the right\sphinxhyphen{}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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{sigma} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{sigma} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}} x name}}} in the declaration of the
notation. It tells to parse \sphinxcode{\sphinxupquote{\DUrole{name}{x}}} as a single identifier (or as the
unnamed variable \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}).


\subparagraph{Binders bound in the notation and parsed as patterns}
\label{\detokenize{user-extensions/syntax-extensions:binders-bound-in-the-notation-and-parsed-as-patterns}}
\sphinxAtStartPar
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}{=>} \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}{=>} \DUrole{name}{x}}}, notations can be
defined so that any \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} can be used in place of the
binder. Here is an example:

\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}

\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}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}} 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:

\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}

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}} 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:

\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}{name}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\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}

\sphinxAtStartPar
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}}}}).


\subparagraph{Binders bound in the notation and parsed as terms}
\label{\detokenize{user-extensions/syntax-extensions:binders-bound-in-the-notation-and-parsed-as-terms}}
\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x : A | 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}{name}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}}}}).

\sphinxAtStartPar
Then, in the rule, \sphinxcode{\sphinxupquote{x name}} is replaced by \sphinxcode{\sphinxupquote{x at level 99 as name}} 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 a name, i.e. an
identifier or \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}.

\sphinxAtStartPar
The notation \sphinxcode{\sphinxupquote{\DUrole{operator}{\{} \DUrole{name}{x} \DUrole{operator}{|} \DUrole{name}{P} \DUrole{operator}{\}}}} is already defined in the standard
library with the \sphinxcode{\sphinxupquote{as name}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_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}}.

\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}

\sphinxAtStartPar
Then, the following works:

\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}

\sphinxAtStartPar
To enforce that the pattern should not be used for printing when it
is just a name, one could have said
\sphinxcode{\sphinxupquote{p at level 99 as strict pattern}}.

\sphinxAtStartPar
Note also that in the absence of a \sphinxcode{\sphinxupquote{as name}}, \sphinxcode{\sphinxupquote{as strict pattern}} or
\sphinxcode{\sphinxupquote{as pattern}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}}}s, the default is to consider sub\sphinxhyphen{}expressions occurring
in binding position and parsed as terms to be \sphinxcode{\sphinxupquote{as name}}.


\subparagraph{Binders bound in the notation and parsed as general binders}
\label{\detokenize{user-extensions/syntax-extensions:binders-bound-in-the-notation-and-parsed-as-general-binders}}
\sphinxAtStartPar
It is also possible to rely on Coq's syntax of binders using the
\sphinxcode{\sphinxupquote{binder}} modifier as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}myforall\PYGZsq{} p , [ P , Q ] }\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{p}\PYG{o}{,} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{p} \PYG{n}{binder}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
In this case, all of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\}}}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}{]}}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}},
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}\}}}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}{]}}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{\textquotesingle{}{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} can be used in place of
the corresponding notation variable. In particular, the binder can
declare implicit arguments:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k}{fun} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{myforall} \PYG{o}{\PYGZob{}}\PYG{n}{a}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{o}{[}\PYG{n}{a}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{,} \PYG{k+kt}{Prop}\PYG{o}{]}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{f} \PYG{n}{eq\PYGZus{}refl}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{f} \PYG{o}{:} \PYG{n}{myforall} \PYG{n}{a}\PYG{o}{,} \PYG{o}{[}\PYG{n}{a} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{k+kt}{Prop}\PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{n}{f} \PYG{l+m+mi}{0} \PYG{n}{eq\PYGZus{}refl}
         \PYG{o}{:} \PYG{o}{(}\PYG{n}{myforall} \PYG{n}{a}\PYG{o}{,} \PYG{o}{[}\PYG{n}{a} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{k+kt}{Prop}\PYG{o}{]}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}

\PYG{k+kn}{Check} \PYG{n}{myforall} \PYG{k}{\PYGZsq{}}\PYG{o}{(}\PYG{o}{(}\PYG{n}{x}\PYG{o}{,}\PYG{n}{y}\PYG{o}{)}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{*}\PYG{n}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{o}{[} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}\PYG{o}{,} \PYG{n}{True} \PYG{o}{]}\PYG{o}{.}
    \PYG{n}{myforall} \PYG{k}{\PYGZsq{}}\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{n}{True}\PYG{o}{]}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

\sphinxAtStartPar
By using instead \sphinxcode{\sphinxupquote{closed binder}}, the same list of binders is allowed
except that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} requires parentheses around.


\subparagraph{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}}
\sphinxAtStartPar
We can also have binders in the right\sphinxhyphen{}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

\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{n}{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}

\sphinxAtStartPar
the next command fails because p does not bind in the instance of n.

\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}

\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}


\subparagraph{Notations with expressions used both as binder and term}
\label{\detokenize{user-extensions/syntax-extensions:notations-with-expressions-used-both-as-binder-and-term}}
\sphinxAtStartPar
It is possible to use parameters of the notation both in term and
binding position. Here is an example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{force} \PYG{n}{n} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{n\PYGZsq{}} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n\PYGZsq{}}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{▢\PYGZus{} n P}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{force} \PYG{n}{n} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \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}{n} \PYG{n}{name}\PYG{o}{,} \PYG{n}{P} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{9}\PYG{o}{,} \PYG{n}{format} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{▢\PYGZus{} n  P}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k}{exists} \PYG{n}{p}\PYG{o}{,} \PYG{n+nb+bp}{▢}\PYG{o}{\PYGZus{}}\PYG{n}{p} \PYG{o}{(}\PYG{n}{p} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{exists} \PYG{n}{p} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n+nb+bp}{▢}\PYG{o}{\PYGZus{}}\PYG{n}{p} \PYG{o}{(}\PYG{n}{p} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

\sphinxAtStartPar
More generally, the parameter can be a pattern, as in the following
variant:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{force2} \PYG{n}{q} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{*}\PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{n\PYGZsq{}} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{n}{fst} \PYG{n}{q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{p\PYGZsq{}}\PYG{o}{,} \PYG{n}{p\PYGZsq{}} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{n}{snd} \PYG{n}{q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{q}\PYG{o}{)}\PYG{o}{.}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{▢\PYGZus{} p P}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{force2} \PYG{n}{p} \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{k}{pattern} \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}{9}\PYG{o}{,} \PYG{n}{format} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{▢\PYGZus{} p  P}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k}{exists} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n+nb+bp}{▢}\PYG{o}{\PYGZus{}}\PYG{o}{(}\PYG{n}{x}\PYG{o}{,}\PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{y} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{exists} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n+nb+bp}{▢}\PYG{o}{\PYGZus{}}\PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{y} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{2}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

\sphinxAtStartPar
This support is experimental. For instance, the notation is used for
printing only if the occurrence of the parameter in term position
comes in the right\sphinxhyphen{}hand side before the occurrence in binding position.


\paragraph{Notations with recursive patterns}
\label{\detokenize{user-extensions/syntax-extensions:notations-with-recursive-patterns}}\label{\detokenize{user-extensions/syntax-extensions:recursivenotations}}
\sphinxAtStartPar
A mechanism is provided for declaring elementary notations with
recursive patterns. The basic example is:

\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}

\sphinxAtStartPar
On the right\sphinxhyphen{}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\sphinxhyphen{}dots notation “\sphinxcode{\sphinxupquote{…}}” used in this manual to denote
a sequence of arbitrary size.

\sphinxAtStartPar
On the left\sphinxhyphen{}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{;}}”).

\sphinxAtStartPar
The right\sphinxhyphen{}hand side must contain a subterm of the form either
\sphinxcode{\sphinxupquote{φ(x, .. φ(y,t) ..)}} or \sphinxcode{\sphinxupquote{φ(y, .. φ(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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
In the example above, the iterator \(φ([~]_E , [~]_I)\) is \(cons [~]_E\, [~]_I\)
and the terminating expression is \sphinxcode{\sphinxupquote{nil}}.

\sphinxAtStartPar
Here is another example with the pattern associating on the left:

\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}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Here is an example with more involved recursive patterns:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[| t * ( x , y , .. , z ) ; ( a , b , .. , c )  * u |]}\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}

\sphinxAtStartPar
To give a flavor of the extent and limits of the mechanism, here is an
example showing a notation for a chain of equalities. It relies on an
artificial expansion of the intended denotation so as to expose a
\sphinxcode{\sphinxupquote{φ(x, .. φ(y,t) ..)}} structure, with the drawback that if ever the
beta\sphinxhyphen{}redexes are contracted, the notations stops to be used for
printing. Support for notations defined in this way should be considered
experimental.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x  ⪯ y  ⪯ ..  ⪯ z  ⪯ t}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=}
  \PYG{o}{(}\PYG{o}{(}\PYG{k}{fun} \PYG{n}{b} \PYG{n}{A} \PYG{n}{a} \PYG{o}{=\PYGZgt{}} \PYG{n}{a} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{b} \PYG{o}{/\PYGZbs{}} \PYG{n}{A} \PYG{n}{b}\PYG{o}{)} \PYG{n}{y} \PYG{o}{..} \PYG{o}{(}\PYG{o}{(}\PYG{k}{fun} \PYG{n}{b} \PYG{n}{A} \PYG{n}{a} \PYG{o}{=\PYGZgt{}} \PYG{n}{a} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{b} \PYG{o}{/\PYGZbs{}} \PYG{n}{A} \PYG{n}{b}\PYG{o}{)} \PYG{n}{z} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{b} \PYG{o}{=\PYGZgt{}} \PYG{n}{b} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{t}\PYG{o}{)}\PYG{o}{)} \PYG{o}{..} \PYG{n}{x}\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{n}{z} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{,} \PYG{n}{t} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note finally that 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}{notation
scopes}}}}.


\paragraph{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}}
\sphinxAtStartPar
Recursive notations can also be used with binders. The basic example
is:

\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}

\sphinxAtStartPar
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}}.

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}}}s
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/extensions/implicit-arguments:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit generalization}}}}) is
used in the binding list, the added binders are taken into account too.

\sphinxAtStartPar
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{name}{nat}\DUrole{operator}{,} \DUrole{name}{a} \DUrole{operator}{=} \DUrole{name}{b}}} is valid.

\sphinxAtStartPar
The variables \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} can also be marked as closed binder in which
case only well\sphinxhyphen{}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.

\sphinxAtStartPar
With closed binders, the recursive sequence in the left\sphinxhyphen{}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:

\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}

\sphinxAtStartPar
A recursive pattern for binders can be used in position of a recursive
pattern for terms. Here is an example:

\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}

\sphinxAtStartPar
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:

\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}


\paragraph{Predefined entries}
\label{\detokenize{user-extensions/syntax-extensions:predefined-entries}}
\sphinxAtStartPar
By default, sub\sphinxhyphen{}expressions are parsed as terms and the corresponding
grammar entry is called \sphinxcode{\sphinxupquote{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}}}:

\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}

\sphinxAtStartPar
In addition to \sphinxcode{\sphinxupquote{global}}, one can restrict the syntax of a
sub\sphinxhyphen{}expression by using the entry names \sphinxcode{\sphinxupquote{ident}}, \sphinxcode{\sphinxupquote{name}} 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\sphinxhyphen{}hand
side. E.g.:
\begin{quote}
\end{quote}

\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}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
As of version 8.13, the entry \sphinxcode{\sphinxupquote{ident}} is a deprecated
alias for \sphinxcode{\sphinxupquote{name}}. In the future, it is planned to strictly
parse an identifier (excluding \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}).
\end{sphinxadmonition}


\paragraph{Custom entries}
\label{\detokenize{user-extensions/syntax-extensions:custom-entries}}\label{\detokenize{user-extensions/syntax-extensions:id7}}\index{Declare Custom Entry (command)@\spxentry{Declare Custom Entry}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Declare-Custom-Entry}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Custom~Entry~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Defines new grammar entries, called \sphinxstyleemphasis{custom
entries}, that can later be referred to using the entry name
\sphinxcode{\sphinxupquote{\DUrole{notation}{custom {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which limits the entry to the
current module.

\sphinxAtStartPar
Non\sphinxhyphen{}local custom entries survive module closing and are
declared when a file is Required.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For instance, we may want to define an ad hoc
parser for arithmetical operations and proceed as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Expr} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{One} \PYG{o}{:} \PYG{n}{Expr}
\PYG{o}{|} \PYG{n}{Mul} \PYG{o}{:} \PYG{n}{Expr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr}
\PYG{o}{|} \PYG{n}{Add} \PYG{o}{:} \PYG{n}{Expr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr}\PYG{o}{.}
    \PYG{n}{Expr} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Expr\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Expr\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Expr\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Expr\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}


\PYG{n}{Declare} \PYG{n}{Custom} \PYG{n}{Entry} \PYG{n}{expr}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[ e ]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{e} \PYG{o}{(}\PYG{n}{e} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{2}\PYG{o}{)}\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}{1}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{One} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \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}{x y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{Mul} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{1}\PYG{o}{,} \PYG{k}{left} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\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}{Add} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{2}\PYG{o}{,} \PYG{k}{left} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{( x )}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr}\PYG{o}{,} \PYG{n}{x} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{2}\PYG{o}{)}\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}{\PYGZob{} x \PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr}\PYG{o}{,} \PYG{n}{x} \PYG{n}{constr}\PYG{o}{)}\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}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{x} \PYG{n}{ident}\PYG{o}{)}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{f} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y} \PYG{n}{z} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{n}{f} \PYG{n}{x}\PYG{o}{\PYGZcb{}}\PYG{o}{]}\PYG{o}{.}
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{Expr}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y} \PYG{n}{z} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{k}{apply} \PYG{n}{f} \PYG{n}{x}\PYG{o}{\PYGZcb{}}\PYG{o}{]}
         \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Notations}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y} \PYG{n}{z} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{n}{f} \PYG{n}{x}\PYG{o}{\PYGZcb{}}\PYG{o}{]}\PYG{o}{.}
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{Expr}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{Add} \PYG{o}{(}\PYG{n}{Add} \PYG{n}{One} \PYG{o}{(}\PYG{n}{Mul} \PYG{n}{y} \PYG{n}{z}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{Expr}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{Expr}\PYG{o}{)}\PYG{o}{,} \PYG{n}{Expr}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Notations}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{k}{fun} \PYG{n}{e} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{e} \PYG{k}{with}
\PYG{o}{|} \PYG{o}{[}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{l+m+mi}{1}\PYG{o}{]}
\PYG{o}{|} \PYG{o}{[}\PYG{n}{x} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z}\PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{n}{z}\PYG{o}{]}
\PYG{o}{|} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{n}{y} \PYG{o}{+} \PYG{n}{e}\PYG{o}{]}
\PYG{k}{end}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{e} \PYG{o}{:} \PYG{n}{Expr} \PYG{o}{=\PYGZgt{}}
    \PYG{k}{match} \PYG{n}{e} \PYG{k}{with}
    \PYG{o}{|} \PYG{o}{[}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{l+m+mi}{1}\PYG{o}{]}
    \PYG{o}{|} \PYG{o}{[}\PYG{n}{x} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z}\PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{n}{z}\PYG{o}{]}
    \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{n}{e} \PYG{o}{+} \PYG{n}{e}\PYG{o}{]}
    \PYG{k}{end}
         \PYG{o}{:} \PYG{n}{Expr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Expr}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Custom entries have levels, like the main grammar of terms and grammar
of patterns have. The lower level is 0 and this is the level used by
default to put rules delimited with tokens on both ends. The level is
left to be inferred by Coq when using \sphinxcode{\sphinxupquote{\DUrole{notation}{in custom {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. The
level is otherwise given explicitly by using the syntax
\sphinxcode{\sphinxupquote{\DUrole{notation}{in custom {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} at level {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}, where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} refers to the level.

\sphinxAtStartPar
Levels are cumulative: a notation at level \sphinxcode{\sphinxupquote{n}} of which the left end
is a term shall use rules at level less than \sphinxcode{\sphinxupquote{n}} to parse this
subterm. More precisely, it shall use rules at level strictly less
than \sphinxcode{\sphinxupquote{n}} if the rule is declared with \sphinxcode{\sphinxupquote{right associativity}} and
rules at level less or equal than \sphinxcode{\sphinxupquote{n}} if the rule is declared with
\sphinxcode{\sphinxupquote{left associativity}}. Similarly, a notation at level \sphinxcode{\sphinxupquote{n}} of which
the right end is a term shall use by default rules at level strictly
less than \sphinxcode{\sphinxupquote{n}} to parse this subterm if the rule is declared left
associative and rules at level less or equal than \sphinxcode{\sphinxupquote{n}} if the rule is
declared right associative. This is what happens for instance in the
rule

\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}{Add} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{2}\PYG{o}{,} \PYG{k}{left} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{x}} is any expression parsed in entry
\sphinxcode{\sphinxupquote{expr}} at level less or equal than \sphinxcode{\sphinxupquote{2}} (including, recursively,
the given rule) and \sphinxcode{\sphinxupquote{y}} is any expression parsed in entry \sphinxcode{\sphinxupquote{expr}}
at level strictly less than \sphinxcode{\sphinxupquote{2}}.

\sphinxAtStartPar
Rules associated with an entry can refer different sub\sphinxhyphen{}entries. The
grammar entry name \sphinxcode{\sphinxupquote{constr}} can be used to refer to the main grammar
of term as in the rule

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x \PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{x} \PYG{n}{constr}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
which indicates that the subterm \sphinxcode{\sphinxupquote{x}} should be
parsed using the main grammar. If not indicated, the level is computed
as for notations in \sphinxcode{\sphinxupquote{constr}}, e.g. using 200 as default level for
inner sub\sphinxhyphen{}expressions. The level can otherwise be indicated explicitly
by using \sphinxcode{\sphinxupquote{constr at level n}} for some \sphinxcode{\sphinxupquote{n}}, or \sphinxcode{\sphinxupquote{constr at next
level}}.

\sphinxAtStartPar
Conversely, custom entries can be used to parse sub\sphinxhyphen{}expressions of the
main grammar, or from another custom entry as is the case in

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[ e ]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{e} \PYG{o}{(}\PYG{n}{e} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
to indicate that \sphinxcode{\sphinxupquote{e}} has to be parsed at level \sphinxcode{\sphinxupquote{2}} of the grammar
associated with the custom entry \sphinxcode{\sphinxupquote{expr}}. The level can be omitted, as in

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[ e ]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{e} \PYG{o}{(}\PYG{n}{e} \PYG{n}{custom} \PYG{n}{expr}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
in which case Coq infer it. If the sub\sphinxhyphen{}expression is at a border of
the notation (as e.g. \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} in \sphinxcode{\sphinxupquote{x + y}}), the level is
determined by the associativity. If the sub\sphinxhyphen{}expression is not at the
border of the notation (as e.g. \sphinxcode{\sphinxupquote{e}} in \sphinxcode{\sphinxupquote{"{[} e {]}}}), the level is
inferred to be the highest level used for the entry. In particular,
this level depends on the highest level existing in the entry at the
time of use of the notation.

\sphinxAtStartPar
In the absence of an explicit entry for parsing or printing a
sub\sphinxhyphen{}expression of a notation in a custom entry, the default is to
consider that this sub\sphinxhyphen{}expression is parsed or printed in the same
custom entry where the notation is defined. In particular, if \sphinxcode{\sphinxupquote{x at
level n}} is used for a sub\sphinxhyphen{}expression of a notation defined in custom
entry \sphinxcode{\sphinxupquote{foo}}, it shall be understood the same as \sphinxcode{\sphinxupquote{x custom foo at
level n}}.

\sphinxAtStartPar
In general, rules are required to be \sphinxstyleemphasis{productive} on the right\sphinxhyphen{}hand
side, i.e. that they are bound to an expression which is not
reduced to a single variable. If the rule is not productive on the
right\sphinxhyphen{}hand side, as it is the case above for

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{( x )}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \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}{2}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
and

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x \PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{x} \PYG{n}{constr}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
it is used as a \sphinxstyleemphasis{grammar coercion} which means that it is used to parse or
print an expression which is not available in the current grammar at the
current level of parsing or printing for this grammar but which is available
in another grammar or in another level of the current grammar. For instance,

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{( x )}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \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}{2}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
tells that parentheses can be inserted to parse or print an expression
declared at level \sphinxcode{\sphinxupquote{2}} of \sphinxcode{\sphinxupquote{expr}} whenever this expression is
expected to be used as a subterm at level 0 or 1.  This allows for
instance to parse and print \sphinxcode{\sphinxupquote{\DUrole{name}{Add} \DUrole{name}{x} \DUrole{name}{y}}} as a subterm of \sphinxcode{\sphinxupquote{\DUrole{name}{Mul} \DUrole{operator}{(}\DUrole{name}{Add}
\DUrole{name}{x} \DUrole{name}{y}\DUrole{operator}{)} \DUrole{name}{z}}} using the syntax \sphinxcode{\sphinxupquote{(x + y) z}}. Similarly,

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x \PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{x} \PYG{n}{constr}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
gives a way to let any arbitrary expression which is not handled by the
custom entry \sphinxcode{\sphinxupquote{expr}} be parsed or printed by the main grammar of term
up to the insertion of a pair of curly brackets.

\sphinxAtStartPar
Another special situation is when parsing global references or
identifiers. To indicate that a custom entry should parse identifiers,
use the following form:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{x} \PYG{n}{ident}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Similarly, to indicate that a custom entry should parse global references
(i.e. qualified or non qualified identifiers), use the following form:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{(}\PYG{k}{in} \PYG{n}{custom} \PYG{n}{expr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{x} \PYG{n}{global}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\index{Print Custom Grammar (command)@\spxentry{Print Custom Grammar}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Custom-Grammar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Custom~Grammar~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This displays the state of the grammar for terms associated with
the custom entry {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Syntax}
\label{\detokenize{user-extensions/syntax-extensions:syntax}}\label{\detokenize{user-extensions/syntax-extensions:notationsyntax}}
\sphinxAtStartPar
Here are the syntax elements used by the various notation commands.
\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{at level {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{in custom {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{at level {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} \DUrole{alternative}{\DUrole{alternative-block}{at {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-level}]{\sphinxcrossref{\DUrole{hole}{level}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{in scope {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} at {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-level}]{\sphinxcrossref{\DUrole{hole}{level}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-binder_interp}]{\sphinxcrossref{\DUrole{hole}{binder\_interp}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-explicit_subentry}]{\sphinxcrossref{\DUrole{hole}{explicit\_subentry}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-binder_interp}]{\sphinxcrossref{\DUrole{hole}{binder\_interp}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{left associativity}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{right associativity}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{no associativity}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{only parsing}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{only printing}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{format {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-explicit_subentry}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-explicit_subentry}]{\sphinxcrossref{\DUrole{hole}{explicit\_subentry}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ident}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{name}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{global}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{bigint}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{strict pattern \DUrole{repeat-wrapper}{\DUrole{repeat}{at level {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{binder}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{closed binder}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{constr \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-level}]{\sphinxcrossref{\DUrole{hole}{level}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-binder_interp}]{\sphinxcrossref{\DUrole{hole}{binder\_interp}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{custom {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-level}]{\sphinxcrossref{\DUrole{hole}{level}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-binder_interp}]{\sphinxcrossref{\DUrole{hole}{binder\_interp}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{pattern \DUrole{repeat-wrapper}{\DUrole{repeat}{at level {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-binder_interp}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-binder_interp}]{\sphinxcrossref{\DUrole{hole}{binder\_interp}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{as ident}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{as name}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{as pattern}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{as strict pattern}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-level}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-level}]{\sphinxcrossref{\DUrole{hole}{level}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{level {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{next level}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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:}
\sphinxAtStartPar
Some 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:}
\sphinxAtStartPar
The notation \sphinxcode{\sphinxupquote{"\{ x \}"}} has a special status in the main grammars of
terms and patterns so 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 \}"}}\sphinxhyphen{}free rule which is \sphinxcode{\sphinxupquote{"y \& z"}}).
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Notations such as \sphinxcode{\sphinxupquote{"( p | q )"}} (or starting with \sphinxcode{\sphinxupquote{"( x | "}},
more generally) are deprecated as they conflict with the syntax for
nested disjunctive patterns (see {\hyperref[\detokenize{language/extensions/match:extendedpatternmatching}]{\sphinxcrossref{\DUrole{std,std-ref}{Extended pattern matching}}}}),
and are not honored in pattern expressions.
\index{Use of ‘string’ Notation is deprecated as it is inconsistent with pattern syntax (warning)@\spxentry{Use of ‘string’ Notation is deprecated as it is inconsistent with pattern syntax}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:warn.Use-of-_u2018string_u2019-Notation-is-deprecated-as-it-is-inconsistent-with-pattern-syntax}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Use~of~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~Notation~is~deprecated~as~it~is~inconsistent~with~pattern~syntax.}}}}
\sphinxAtStartPar
This warning is disabled by default to avoid spurious diagnostics
due to legacy notation in the Coq standard library.
It can be turned on with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}w disj\sphinxhyphen{}pattern\sphinxhyphen{}notation}} flag.

\end{fulllineitems}\end{savenotes}

\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
As of version 8.13, the entry \sphinxcode{\sphinxupquote{ident}} is a deprecated alias for
\sphinxcode{\sphinxupquote{name}}. In the future, it is planned to strictly parse an
identifier (to the exclusion of \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}). If the intent was to use
\sphinxcode{\sphinxupquote{ident}} as an identifier (excluding \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}), just silence the warning with
\sphinxcode{\sphinxupquote{\DUrole{notation}{Set Warnings "\sphinxhyphen{}deprecated\sphinxhyphen{}ident\sphinxhyphen{}entry"}}} and it should automatically
get its intended meaning in version 8.15.

\sphinxAtStartPar
Similarly, \sphinxcode{\sphinxupquote{as ident}} is a deprecated alias for \sphinxcode{\sphinxupquote{as name}}, which
will only accept an identifier in the future.  If the
intent was to use \sphinxcode{\sphinxupquote{as ident}} as an identifier
(excluding \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}), just silence the warning with
\sphinxcode{\sphinxupquote{\DUrole{notation}{Set Warnings "\sphinxhyphen{}deprecated\sphinxhyphen{}as\sphinxhyphen{}ident\sphinxhyphen{}kind"}}}.

\sphinxAtStartPar
However, this deprecation does not apply to custom entries, where it
already denotes an identifier, as expected.
\end{sphinxadmonition}


\subsubsection{Notation scopes}
\label{\detokenize{user-extensions/syntax-extensions:notation-scopes}}\label{\detokenize{user-extensions/syntax-extensions:scopes}}
\sphinxAtStartPar
A \sphinxstyleemphasis{notation scope} is a set of notations for terms with their
interpretations. Notation scopes provide a weak, purely
syntactic form of notation overloading: a symbol may
refer to different definitions depending on which notation scopes
are currently open.  For instance, the infix symbol \sphinxcode{\sphinxupquote{+}} can be
used to refer to distinct definitions of the addition operator,
such as for natural numbers, integers or reals.
Notation scopes can include an interpretation for numbers and
strings with the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} and {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}} commands.
\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-scope}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}

\sphinxAtStartPar
Each notation scope has a single {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_name}}}}}, which by convention
ends with the suffix "\_scope", as in "nat\_scope".  One or more {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_key}}}}}s
(delimiting keys) may be associated with a notation scope with the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Delimit-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Delimit Scope}}}}} command.
Most commands use {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_name}}}}}; {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_key}}}}}s are used within {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}s.
\index{Declare Scope (command)@\spxentry{Declare Scope}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Declare-Scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}}}
\sphinxAtStartPar
Declares a new notation scope. Note that the initial
state of Coq declares the following notation scopes:
\sphinxcode{\sphinxupquote{core\_scope}}, \sphinxcode{\sphinxupquote{type\_scope}}, \sphinxcode{\sphinxupquote{function\_scope}}, \sphinxcode{\sphinxupquote{nat\_scope}},
\sphinxcode{\sphinxupquote{bool\_scope}}, \sphinxcode{\sphinxupquote{list\_scope}}, \sphinxcode{\sphinxupquote{int\_scope}}, \sphinxcode{\sphinxupquote{uint\_scope}}.

\sphinxAtStartPar
Use commands such as {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} to add notations to the scope.

\end{fulllineitems}\end{savenotes}



\paragraph{Global interpretation rules for notations}
\label{\detokenize{user-extensions/syntax-extensions:global-interpretation-rules-for-notations}}
\sphinxAtStartPar
At any time, the interpretation of a notation for a term is done within
a \sphinxstyleemphasis{stack} of notation scopes and lonely notations. If a
notation is defined in multiple scopes, Coq uses the interpretation from
the most recently opened notation scope or declared lonely notation.

\sphinxAtStartPar
Note that "stack" is a misleading name.  Each scope or lonely notation can only appear in
the stack once.  New items are pushed onto the top of the stack, except that
adding a item that's already in the stack moves it to the top of the stack instead.
Scopes are removed by name (e.g. by {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Close-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Close Scope}}}}}) wherever they are in the
stack, rather than through "pop" operations.

\sphinxAtStartPar
Use the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Visibility}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Visibility}}}}} command to display the current notation scope stack.
\index{Open Scope (command)@\spxentry{Open Scope}\spxextra{command}}

\begin{savenotes}\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}}}}}}}}
\sphinxAtStartPar
Adds a scope to the notation scope stack.  If the scope is already present,
the command moves it to the top of the stack.

\sphinxAtStartPar
If the command appears in a section: By default, the scope is only added within the
section.  Specifying {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} marks the scope for export as part of the current
module.  Specifying {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} behaves like the default.

\sphinxAtStartPar
If the command does not appear in a section: By default, the scope marks the scope for
export as part of the current module.  Specifying {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} prevents exporting the scope.
Specifying {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} behaves like the default.

\end{fulllineitems}\end{savenotes}

\index{Close Scope (command)@\spxentry{Close Scope}\spxextra{command}}

\begin{savenotes}\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}}}}}}}}
\sphinxAtStartPar
Removes a scope from the notation scope stack.

\sphinxAtStartPar
If the command appears in a section: By default, the scope is only removed within the
section.  Specifying {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} marks the scope removal for export as part of the current
module.  Specifying {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} behaves like the default.

\sphinxAtStartPar
If the command does not appear in a section: By default, the scope marks the scope removal for
export as part of the current module.  Specifying {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} prevents exporting the removal.
Specifying {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} behaves like the default.

\end{fulllineitems}\end{savenotes}



\paragraph{Local interpretation rules for notations}
\label{\detokenize{user-extensions/syntax-extensions:local-interpretation-rules-for-notations}}\label{\detokenize{user-extensions/syntax-extensions:localinterpretationrulesfornotations}}
\sphinxAtStartPar
In addition to the global rules of interpretation of notations, some
ways to change the interpretation of subterms are available.


\subparagraph{Opening a notation scope locally}
\label{\detokenize{user-extensions/syntax-extensions:opening-a-notation-scope-locally}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-term_scope}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-term_scope}]{\sphinxcrossref{\DUrole{hole}{term\_scope}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}} \% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The notation scope stack can be locally extended within
a {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} with the syntax
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}} (or simply \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}} for atomic terms).

\sphinxAtStartPar
In this case, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is
interpreted in the scope stack extended with the scope bound to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}}.
\index{Delimit Scope (command)@\spxentry{Delimit Scope}\spxextra{command}}

\begin{savenotes}\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_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}~with~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}}}
\sphinxAtStartPar
Binds the delimiting key {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_key}}}}} to a scope.

\end{fulllineitems}\end{savenotes}

\index{Undelimit Scope (command)@\spxentry{Undelimit Scope}\spxextra{command}}

\begin{savenotes}\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_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}}}
\sphinxAtStartPar
Removes the delimiting keys associated with a scope.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
The arguments of an {\hyperref[\detokenize{user-extensions/syntax-extensions:abbreviations}]{\sphinxcrossref{\DUrole{std,std-ref}{abbreviation}}}} can be interpreted
in a scope stack locally extended with a given scope by using the modifier
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} in scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}}.s


\subparagraph{Binding types or coercion classes to a notation scope}
\label{\detokenize{user-extensions/syntax-extensions:binding-types-or-coercion-classes-to-a-notation-scope}}\index{Bind Scope (command)@\spxentry{Bind Scope}\spxextra{command}}

\begin{savenotes}\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_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Binds the notation scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_name}}}}} to the type or coercion class {\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{class}}}}}.
When bound, arguments of that type for any function will be interpreted in
that scope by default.  This default can be overridden for individual functions
with the {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command.  The association may be convenient
when a notation scope is naturally associated with a {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} (e.g.
\sphinxcode{\sphinxupquote{nat}} and the natural numbers).

\sphinxAtStartPar
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}{\sphinxhyphen{}>} \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}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{U} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\PYG{n}{Declare} \PYG{k+kn}{Scope} \PYG{n}{U\PYGZus{}scope}\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}

\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{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{z} \PYG{o}{:} \PYG{n}{U}\PYG{o}{)} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
    \PYG{n}{P} \PYG{n}{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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{U}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
When active, a bound scope has effect on all defined functions
(even if they are defined after the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Bind-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Bind Scope}}}}} directive), except
if argument scopes were assigned explicitly using the
{\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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}\end{savenotes}



\paragraph{The \sphinxstyleliteralintitle{\sphinxupquote{type\_scope}} notation scope}
\label{\detokenize{user-extensions/syntax-extensions:the-type-scope-notation-scope}}
\index{type\_scope@\spxentry{type\_scope}}\ignorespaces 
\sphinxAtStartPar
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 and hypotheses: match goal}}}}), 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.


\paragraph{The \sphinxstyleliteralintitle{\sphinxupquote{function\_scope}} notation scope}
\label{\detokenize{user-extensions/syntax-extensions:the-function-scope-notation-scope}}
\index{function\_scope@\spxentry{function\_scope}}\ignorespaces 
\sphinxAtStartPar
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}} instance, 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}{\sphinxhyphen{}>} \DUrole{name}{B}}}.


\paragraph{Notation scopes used in the standard library of Coq}
\label{\detokenize{user-extensions/syntax-extensions:notation-scopes-used-in-the-standard-library-of-coq}}\label{\detokenize{user-extensions/syntax-extensions:id8}}
\sphinxAtStartPar
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:cmd.Print-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Scope}}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{type\_scope}}}] \leavevmode
\sphinxAtStartPar
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
\sphinxAtStartPar
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
\sphinxAtStartPar
This scope includes the standard arithmetical operators and relations on type
nat. Positive integer numbers 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{name}{nat}}} (see above).

\item[{\sphinxcode{\sphinxupquote{N\_scope}}}] \leavevmode
\sphinxAtStartPar
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 numbers as closed terms of type \sphinxcode{\sphinxupquote{\DUrole{name}{N}}}.

\item[{\sphinxcode{\sphinxupquote{Z\_scope}}}] \leavevmode
\sphinxAtStartPar
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 numbers as closed terms of type \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}}.

\item[{\sphinxcode{\sphinxupquote{positive\_scope}}}] \leavevmode
\sphinxAtStartPar
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 numbers as closed
terms of type \sphinxcode{\sphinxupquote{\DUrole{name}{positive}}}.

\item[{\sphinxcode{\sphinxupquote{Q\_scope}}}] \leavevmode
\sphinxAtStartPar
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\sphinxhyphen{}
denominator cross\sphinxhyphen{}product) and comes with an interpretation for numbers
as closed terms of type \sphinxcode{\sphinxupquote{\DUrole{name}{Q}}}.

\item[{\sphinxcode{\sphinxupquote{Qc\_scope}}}] \leavevmode
\sphinxAtStartPar
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{R\_scope}}}] \leavevmode
\sphinxAtStartPar
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 numbers using the \sphinxcode{\sphinxupquote{\DUrole{name}{IZR}}} morphism from binary
integer numbers to \sphinxcode{\sphinxupquote{\DUrole{name}{R}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{pow\_pos}}} for potential exponent parts.

\item[{\sphinxcode{\sphinxupquote{bool\_scope}}}] \leavevmode
\sphinxAtStartPar
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{name}{bool}}} (see above).

\item[{\sphinxcode{\sphinxupquote{list\_scope}}}] \leavevmode
\sphinxAtStartPar
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{name}{list}}} (see above).

\item[{\sphinxcode{\sphinxupquote{core\_scope}}}] \leavevmode
\sphinxAtStartPar
This scope includes the notation for pairs. It is delimited by the key \sphinxcode{\sphinxupquote{core}}.

\item[{\sphinxcode{\sphinxupquote{string\_scope}}}] \leavevmode
\sphinxAtStartPar
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/core/basic: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
\sphinxAtStartPar
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\sphinxhyphen{}digit number (possibly with leading 0s), 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{name}{ascii}}}.

\end{description}


\paragraph{Displaying information about scopes}
\label{\detokenize{user-extensions/syntax-extensions:displaying-information-about-scopes}}\index{Print Visibility (command)@\spxentry{Print Visibility}\spxextra{command}}

\begin{savenotes}\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~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Displays the current notation scope stack. 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.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}} is specified,
displays the current notation scope stack
as if the scope \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}} is pushed on top of the stack. This is
useful to see how a subterm occurring locally in the scope is
interpreted.

\end{fulllineitems}\end{savenotes}

\index{Print Scopes (command)@\spxentry{Print Scopes}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Displays, for each existing notation scope, all accessible notations
(whether or not currently in the notation scope stack),
the most\sphinxhyphen{}recently defined delimiting key and the class the notation scope is bound to.
The display also includes lonely notations.

\sphinxAtStartPar
Use the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Visibility}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Visibility}}}}} command to display the current notation scope stack.

\end{fulllineitems}\end{savenotes}

\index{Print Scope (command)@\spxentry{Print Scope}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}}}
\sphinxAtStartPar
Displays all notations defined in the notation scope \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}}.
It also displays the delimiting key and the class to which the
scope is bound, if any.

\end{fulllineitems}\end{savenotes}



\subsubsection{Abbreviations}
\label{\detokenize{user-extensions/syntax-extensions:abbreviations}}\label{\detokenize{user-extensions/syntax-extensions:id9}}\index{Notation (abbreviation) (command)@\spxentry{Notation (abbreviation)}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation-(abbreviation)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Notation~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{parm}}$}}}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~)}\DUrole{notation-sup}{?}}}}}}~
\sphinxAtStartPar
Defines an abbreviation {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} with the parameters \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{parm}}$}}}}}}}.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which limits the notation to the
current module.

\sphinxAtStartPar
An \sphinxstyleemphasis{abbreviation} is a name, possibly applied to arguments, that
denotes a (presumably) more complex expression. Here are examples:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{n}{Nlist} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{list} \PYG{n}{nat}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\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{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{n}{Nlist}
\end{sphinxVerbatim}

\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}

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{n}{Plus1} \PYG{n}{B} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{n}{B} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Compute} \PYG{o}{(}\PYG{n}{Plus1} \PYG{l+m+mi}{3}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{=} \PYG{l+m+mi}{4}
         \PYG{o}{:} \PYG{n}{nat}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
An abbreviation is bound to an absolute name as an ordinary definition is
and it also can be referred to by a qualified name.

\sphinxAtStartPar
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:

\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}

\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}

\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{n}{nat}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
Like for notations, if the right\sphinxhyphen{}hand side of an abbreviation is a
partially applied constant, the abbreviation inherits the implicit
arguments and notation scopes of the constant. As an
exception, if the right\sphinxhyphen{}hand side is just of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{@{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}},
this conventionally stops the inheritance of implicit arguments.

\sphinxAtStartPar
Like for notations, it is possible to bind binders in
abbreviations. Here is an example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{force2} \PYG{n}{q} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{*}\PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{n\PYGZsq{}} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{n}{fst} \PYG{n}{q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{p\PYGZsq{}}\PYG{o}{,} \PYG{n}{p\PYGZsq{}} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{n}{snd} \PYG{n}{q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{q}\PYG{o}{)}\PYG{o}{.}

\PYG{k+kn}{Notation} \PYG{n}{F} \PYG{n}{p} \PYG{n}{P} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{force2} \PYG{n}{p} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{k}{exists} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{F} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,}\PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{y} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\end{fulllineitems}\end{savenotes}



\subsubsection{Numbers and strings}
\label{\detokenize{user-extensions/syntax-extensions:numbers-and-strings}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-primitive_notations}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-primitive_notations}]{\sphinxcrossref{\DUrole{hole}{primitive\_notations}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-number}]{\sphinxcrossref{\DUrole{hole}{number}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Numbers and strings have no predefined semantics in the calculus. They are
merely notations that can be bound to objects through the notation mechanism.
Initially, numbers 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:}
\sphinxAtStartPar
Negative integers are not at the same level as \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}, for this
would make precedence unnatural.
\end{sphinxadmonition}


\paragraph{Number notations}
\label{\detokenize{user-extensions/syntax-extensions:number-notations}}\label{\detokenize{user-extensions/syntax-extensions:id10}}\index{Number Notation (command)@\spxentry{Number Notation}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Number~Notation~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-number_modifier}]{\sphinxcrossref{\DUrole{hole}{number\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~)}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-number_modifier}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-number_modifier}]{\sphinxcrossref{\DUrole{hole}{number\_modifier}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{warning after {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{abstract after {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-number_string_via}]{\sphinxcrossref{\DUrole{hole}{number\_string\_via}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-number_string_via}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-number_string_via}]{\sphinxcrossref{\DUrole{hole}{number\_string\_via}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{via {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} mapping {[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} => {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[} {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} {]} => {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
This command allows the user to customize the way number literals
are parsed and printed.
\begin{quote}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}}] \leavevmode
\sphinxAtStartPar
the name of an inductive type,
while \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}}}} should be the names of the
parsing and printing functions, respectively.  The parsing function
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} should have one of the following types:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Number.int \sphinxhyphen{}> {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Number.int \sphinxhyphen{}> option {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Number.uint \sphinxhyphen{}> {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Number.uint \sphinxhyphen{}> option {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Z \sphinxhyphen{}> {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Z \sphinxhyphen{}> option {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{PrimInt63.int \sphinxhyphen{}> {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{PrimInt63.int \sphinxhyphen{}> option {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Number.number \sphinxhyphen{}> {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Number.number \sphinxhyphen{}> option {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\end{itemize}

\sphinxAtStartPar
And the printing function \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}}}} should have one of the
following types:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> Number.int}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> option Number.int}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> Number.uint}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> option Number.uint}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> Z}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> option Z}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> PrimInt63.int}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> option PrimInt63.int}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> Number.number}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> option Number.number}}}

\end{itemize}

\sphinxAtStartPar
When parsing, the application of the parsing function
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} to the number will be fully reduced, and universes
of the resulting term will be refreshed.

\sphinxAtStartPar
Note that only fully\sphinxhyphen{}reduced ground terms (terms containing only
function application, constructors, inductive type families,
sorts, primitive integers, primitive floats, primitive arrays and type
constants for primitive types) will be considered for printing.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
For example, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}} can be \sphinxcode{\sphinxupquote{\DUrole{notation}{PrimInt63.int}}},
in which case \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}}}} takes \sphinxcode{\sphinxupquote{\DUrole{notation}{PrimInt63.int\_wrapper}}} as input
instead of \sphinxcode{\sphinxupquote{\DUrole{notation}{PrimInt63.int}}}. See below for an
{\hyperref[\detokenize{user-extensions/syntax-extensions:example-number-notation-primitive-int}]{\sphinxcrossref{\DUrole{std,std-ref}{example}}}}.
\end{sphinxadmonition}

\end{description}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:number-string-via}}\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{via {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{ind}}$}}}} mapping {[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constant}}$}}}} => {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constructor}}$}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} {]}}}}}] \leavevmode
\sphinxAtStartPar
When using this option, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}} no
longer needs to be an inductive type and is instead mapped to the
inductive type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{ind}}$}}}}}}} according to the provided
list of pairs, whose first component \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constant}}$}}}}}}} is a
constant of type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}
(or a function of type \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\_ \sphinxhyphen{}>}\DUrole{notation-sup}{*}} {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}) and the second a
constructor of type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{ind}}$}}}}}}}. The type
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}} is then replaced by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{ind}}$}}}}}}} in the
above parser and printer types.

\sphinxAtStartPar
When \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constant}}$}}}}}}} is surrounded by square brackets,
all the implicit arguments of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constant}}$}}}}}}} (whether maximally inserted or not) are ignored
when translating to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constructor}}$}}}}}}} (i.e., before
applying \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}}}}) and replaced with implicit
argument holes \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}} when translating from
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constructor}}$}}}}}}} to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constant}}$}}}}}}} (after
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}}). See below for an {\hyperref[\detokenize{user-extensions/syntax-extensions:example-number-notation-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{example}}}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The implicit status of the arguments is considered
only at notation declaration time, any further
modification of this status has no impact
on the previously declared notations.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
In case of multiple implicit options (for instance
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Arguments} \DUrole{name}{eq\_refl} \DUrole{operator}{\{}\DUrole{name}{A}\DUrole{operator}{\}\%}\DUrole{name}{type\_scope} \DUrole{operator}{\{}\DUrole{name}{x}\DUrole{operator}{\},} \DUrole{operator}{{[}\_{]}} \DUrole{operator}{\_}}}), an
argument is considered implicit when it is implicit in any of the
options.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
To use a {\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort}}}}} as the target type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}, use an {\hyperref[\detokenize{user-extensions/syntax-extensions:abbreviations}]{\sphinxcrossref{\DUrole{std,std-ref}{abbreviation}}}}
as in the {\hyperref[\detokenize{user-extensions/syntax-extensions:example-number-notation-non-inductive}]{\sphinxcrossref{\DUrole{std,std-ref}{example below}}}}.
\end{sphinxadmonition}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{warning after {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}}}] \leavevmode
\sphinxAtStartPar
displays a warning message about a possible stack
overflow when calling \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} to parse a literal larger than \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}}.
\index{Stack overflow or segmentation fault happens when working with large numbers in ‘type’ (threshold may vary depending on your system limits and on the command executed) (warning)@\spxentry{Stack overflow or segmentation fault happens when working with large numbers in ‘type’ (threshold may vary depending on your system limits and on the command executed)}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:warn.Stack-overflow-or-segmentation-fault-happens-when-working-with-large-numbers-in-_u2018type_u2019-(threshold-may-vary-depending-on-your-system-limits-and-on-the-command-executed)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Stack~overflow~or~segmentation~fault~happens~when~working~with~large~numbers~in~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~(threshold~may~vary~depending~on~your~system~limits~and~on~the~command~executed).}}}}
\sphinxAtStartPar
When a {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} is registered in the current scope
with \sphinxcode{\sphinxupquote{\DUrole{notation}{(warning after {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}})}}}, this warning is emitted when
parsing a number greater than or equal to {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bignat}}}}}.

\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{abstract after {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}}}] \leavevmode
\sphinxAtStartPar
returns \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}} m)}}} when parsing a literal
\sphinxcode{\sphinxupquote{\DUrole{notation}{m}}} that's greater than \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}}}}} rather than reducing it to a normal form.
Here \sphinxcode{\sphinxupquote{\DUrole{name}{m}}} will be a
\sphinxcode{\sphinxupquote{\DUrole{name}{Number}\DUrole{operator}{.}\DUrole{name}{int}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Number}\DUrole{operator}{.}\DUrole{name}{uint}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{Number}\DUrole{operator}{.}\DUrole{name}{number}}}, depending on the
type of the parsing function \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}}. This allows for a
more compact representation of literals in types such as \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}},
and limits parse failures due to stack overflow.  Note that a
warning will be emitted when an integer larger than {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bignat}}}}}
is parsed.  Note that \sphinxcode{\sphinxupquote{\DUrole{notation}{(abstract after {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}})}}} has no effect
when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} lands in an \sphinxcode{\sphinxupquote{\DUrole{name}{option}}} type.
\index{To avoid stack overflow, large numbers in ‘type’ are interpreted as applications of ‘qualid’ (warning)@\spxentry{To avoid stack overflow, large numbers in ‘type’ are interpreted as applications of ‘qualid’}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:warn.To-avoid-stack-overflow,-large-numbers-in-_u2018type_u2019-are-interpreted-as-applications-of-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{To~avoid~stack~overflow,~large~numbers~in~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~are~interpreted~as~applications~of~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}.}}}}
\sphinxAtStartPar
When a {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} is registered in the current scope
with \sphinxcode{\sphinxupquote{\DUrole{notation}{(abstract after {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\DUrole{hole}{bignat}}}})}}}, this warning is emitted when
parsing a number greater than or equal to {\hyperref[\detokenize{language/core/basic:grammar-token-bignat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bignat}}}}}.
Typically, this indicates that the fully computed representation
of numbers can be so large that non\sphinxhyphen{}tail\sphinxhyphen{}recursive OCaml
functions run out of stack space when trying to walk them.

\end{fulllineitems}\end{savenotes}

\index{The 'abstract after' directive has no effect when the parsing function (‘qualid’) targets an option type (warning)@\spxentry{The 'abstract after' directive has no effect when the parsing function (‘qualid’) targets an option type}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:warn.The-'abstract-after'-directive-has-no-effect-when-the-parsing-function-(_u2018qualid_u2019)-targets-an-option-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~\textquotesingle{}abstract~after\textquotesingle{}~directive~has~no~effect~when~the~parsing~function~({\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}})~targets~an~option~type.}}}}
\sphinxAtStartPar
As noted above, the \sphinxcode{\sphinxupquote{\DUrole{notation}{(abstract after {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}})}}} directive has no
effect when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} lands in an \sphinxcode{\sphinxupquote{\DUrole{name}{option}}} type.

\end{fulllineitems}\end{savenotes}

\index{'via' and 'abstract' cannot be used together (error)@\spxentry{'via' and 'abstract' cannot be used together}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.'via'-and-'abstract'-cannot-be-used-together}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\textquotesingle{}via\textquotesingle{}~and~\textquotesingle{}abstract\textquotesingle{}~cannot~be~used~together.}}}}
\sphinxAtStartPar
With the \sphinxcode{\sphinxupquote{\DUrole{notation}{abstract after}}} option, the parser function
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} does not reduce large numbers to a normal form,
which prevents doing the translation given in the \sphinxcode{\sphinxupquote{\DUrole{notation}{mapping}}} list.

\end{fulllineitems}\end{savenotes}


\end{description}
\end{quote}
\index{Cannot interpret this number as a value of type ‘type’ (error)@\spxentry{Cannot interpret this number as a value of type ‘type’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Cannot-interpret-this-number-as-a-value-of-type-_u2018type_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~interpret~this~number~as~a~value~of~type~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
\sphinxAtStartPar
The number notation registered for {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} does not support
the given number.  This error is given when the interpretation
function returns \sphinxcode{\sphinxupquote{\DUrole{name}{None}}}, or if the interpretation is registered
only for integers or non\sphinxhyphen{}negative integers, and the given number
has a fractional or exponent part or is negative.

\end{fulllineitems}\end{savenotes}

\index{overflow in int63 literal ‘bigint’ (error)@\spxentry{overflow in int63 literal ‘bigint’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.overflow-in-int63-literal-_u2018bigint_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{overflow~in~int63~literal~{\hyperref[\detokenize{language/core/basic:grammar-token-bigint}]{\sphinxcrossref{\DUrole{hole}{bigint}}}}}}}}
\sphinxAtStartPar
The constant's absolute value is too big to fit into a 63\sphinxhyphen{}bit integer \sphinxcode{\sphinxupquote{\DUrole{notation}{PrimInt63.int}}}.

\end{fulllineitems}\end{savenotes}

\index{‘qualid’ should go from Number.int to ‘type’ or (option ‘type’). Instead of Number.int, the types Number.uint or Z or PrimInt63.pos\_neg\_int63 or Number.number could be used (you may need to require BinNums or Number or PrimInt63 first) (error)@\spxentry{‘qualid’ should go from Number.int to ‘type’ or (option ‘type’). Instead of Number.int, the types Number.uint or Z or PrimInt63.pos\_neg\_int63 or Number.number could be used (you may need to require BinNums or Number or PrimInt63 first)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn._u2018qualid_u2019-should-go-from-Number.int-to-_u2018type_u2019-or-(option-_u2018type_u2019).-Instead-of-Number.int,-the-types-Number.uint-or-Z-or-PrimInt63.pos_neg_int63-or-Number.number-could-be-used-(you-may-need-to-require-BinNums-or-Number-or-PrimInt63-first)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}~should~go~from~Number.int~to~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~or~(option~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}).~Instead~of~Number.int,~the~types~Number.uint~or~Z~or~PrimInt63.pos\_neg\_int63~or~Number.number~could~be~used~(you~may~need~to~require~BinNums~or~Number~or~PrimInt63~first).}}}}
\sphinxAtStartPar
The parsing function given to the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}}
command is not of the right type.

\end{fulllineitems}\end{savenotes}

\index{‘qualid’ should go from ‘type’ to Number.int or (option Number.int). Instead of Number.int, the types Number.uint or Z or PrimInt63.pos\_neg\_int63 or Number.number could be used (you may need to require BinNums or Number or PrimInt63 first) (error)@\spxentry{‘qualid’ should go from ‘type’ to Number.int or (option Number.int). Instead of Number.int, the types Number.uint or Z or PrimInt63.pos\_neg\_int63 or Number.number could be used (you may need to require BinNums or Number or PrimInt63 first)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn._u2018qualid_u2019-should-go-from-_u2018type_u2019-to-Number.int-or-(option-Number.int).-Instead-of-Number.int,-the-types-Number.uint-or-Z-or-PrimInt63.pos_neg_int63-or-Number.number-could-be-used-(you-may-need-to-require-BinNums-or-Number-or-PrimInt63-first)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}~should~go~from~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~to~Number.int~or~(option~Number.int).~Instead~of~Number.int,~the~types~Number.uint~or~Z~or~PrimInt63.pos\_neg\_int63~or~Number.number~could~be~used~(you~may~need~to~require~BinNums~or~Number~or~PrimInt63~first).}}}}
\sphinxAtStartPar
The printing function given to the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}}
command is not of the right type.

\end{fulllineitems}\end{savenotes}

\index{Unexpected term ‘term’ while parsing a number notation (error)@\spxentry{Unexpected term ‘term’ while parsing a number notation}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Unexpected-term-_u2018term_u2019-while-parsing-a-number-notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unexpected~term~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~while~parsing~a~number~notation.}}}}
\sphinxAtStartPar
Parsing functions must always return ground terms, made up of
function application, constructors, inductive type families, sorts and primitive
integers.  Parsing functions may not return terms containing
axioms, bare (co)fixpoints, lambdas, etc.

\end{fulllineitems}\end{savenotes}

\index{Unexpected non\sphinxhyphen{}option term ‘term’ while parsing a number notation (error)@\spxentry{Unexpected non\sphinxhyphen{}option term ‘term’ while parsing a number notation}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Unexpected-non-option-term-_u2018term_u2019-while-parsing-a-number-notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unexpected~non\sphinxhyphen{}option~term~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~while~parsing~a~number~notation.}}}}
\sphinxAtStartPar
Parsing functions expected to return an \sphinxcode{\sphinxupquote{\DUrole{name}{option}}} must always
return a concrete \sphinxcode{\sphinxupquote{\DUrole{name}{Some}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{None}}} when applied to a
concrete number expressed as a (hexa)decimal.  They may not return
opaque constants.

\end{fulllineitems}\end{savenotes}

\index{Multiple 'via' options (error)@\spxentry{Multiple 'via' options}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Multiple-'via'-options}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Multiple~\textquotesingle{}via\textquotesingle{}~options.}}}}
\sphinxAtStartPar
At most one \sphinxcode{\sphinxupquote{\DUrole{name}{via}}} option can be given.

\end{fulllineitems}\end{savenotes}

\index{Multiple 'warning after' or 'abstract after' options (error)@\spxentry{Multiple 'warning after' or 'abstract after' options}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Multiple-'warning-after'-or-'abstract-after'-options}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Multiple~\textquotesingle{}warning~after\textquotesingle{}~or~\textquotesingle{}abstract~after\textquotesingle{}~options.}}}}
\sphinxAtStartPar
At most one \sphinxcode{\sphinxupquote{\DUrole{name}{warning} \DUrole{keyword}{after}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{abstract} \DUrole{keyword}{after}}} option can be given.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{String notations}
\label{\detokenize{user-extensions/syntax-extensions:string-notations}}\label{\detokenize{user-extensions/syntax-extensions:id11}}\index{String Notation (command)@\spxentry{String Notation}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{String~Notation~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-number_string_via}]{\sphinxcrossref{\DUrole{hole}{number\_string\_via}}}}~)}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}}}}}~\begin{quote}

\sphinxAtStartPar
Allows the user to customize how strings are parsed and printed.
\begin{quote}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}}] \leavevmode
\sphinxAtStartPar
the name of an inductive type,
while \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}}}} should be the names of the
parsing and printing functions, respectively.  The parsing function
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} should have one of the following types:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Byte.byte \sphinxhyphen{}> {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Byte.byte \sphinxhyphen{}> option {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{list Byte.byte \sphinxhyphen{}> {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{list Byte.byte \sphinxhyphen{}> option {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}

\end{itemize}

\sphinxAtStartPar
The printing function \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}}}} should have one of the
following types:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> Byte.byte}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> option Byte.byte}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> list Byte.byte}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}} \sphinxhyphen{}> option (list Byte.byte)}}}

\end{itemize}

\sphinxAtStartPar
When parsing, the application of the parsing function
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} to the string will be fully reduced, and universes
of the resulting term will be refreshed.

\sphinxAtStartPar
Note that only fully\sphinxhyphen{}reduced ground terms (terms containing only
function application, constructors, inductive type families,
sorts, primitive integers, primitive floats, primitive arrays and type
constants for primitive types) will be considered for printing.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{via {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{ind}}$}}}} mapping {[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constant}}$}}}} => {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{constructor}}$}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} {]}}}}}] \leavevmode
\sphinxAtStartPar
works as for {\hyperref[\detokenize{user-extensions/syntax-extensions:number-string-via}]{\sphinxcrossref{\DUrole{std,std-ref}{number notations above}}}}.

\end{description}
\end{quote}
\end{quote}
\index{Cannot interpret this string as a value of type ‘type’ (error)@\spxentry{Cannot interpret this string as a value of type ‘type’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Cannot-interpret-this-string-as-a-value-of-type-_u2018type_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~interpret~this~string~as~a~value~of~type~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}~\begin{quote}

\sphinxAtStartPar
The string notation registered for {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} does not support
the given string.  This error is given when the interpretation
function returns \sphinxcode{\sphinxupquote{\DUrole{name}{None}}}.
\end{quote}
\index{‘qualid’ should go from Byte.byte or (list Byte.byte) to ‘type’ or (option ‘type’) (error)@\spxentry{‘qualid’ should go from Byte.byte or (list Byte.byte) to ‘type’ or (option ‘type’)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn._u2018qualid_u2019-should-go-from-Byte.byte-or-(list-Byte.byte)-to-_u2018type_u2019-or-(option-_u2018type_u2019)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}~should~go~from~Byte.byte~or~(list~Byte.byte)~to~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~or~(option~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}).}}}}
\sphinxAtStartPar
The parsing function given to the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}}
command is not of the right type.

\end{fulllineitems}\end{savenotes}

\index{‘qualid’ should go from ‘type’ to Byte.byte or (option Byte.byte) or (list Byte.byte) or (option (list Byte.byte)) (error)@\spxentry{‘qualid’ should go from ‘type’ to Byte.byte or (option Byte.byte) or (list Byte.byte) or (option (list Byte.byte))}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn._u2018qualid_u2019-should-go-from-_u2018type_u2019-to-Byte.byte-or-(option-Byte.byte)-or-(list-Byte.byte)-or-(option-(list-Byte.byte))}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}~should~go~from~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~to~Byte.byte~or~(option~Byte.byte)~or~(list~Byte.byte)~or~(option~(list~Byte.byte)).}}}}
\sphinxAtStartPar
The printing function given to the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}}
command is not of the right type.

\end{fulllineitems}\end{savenotes}

\index{Unexpected term ‘term’ while parsing a string notation (error)@\spxentry{Unexpected term ‘term’ while parsing a string notation}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Unexpected-term-_u2018term_u2019-while-parsing-a-string-notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unexpected~term~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~while~parsing~a~string~notation.}}}}
\sphinxAtStartPar
Parsing functions must always return ground terms, made up of
function application, constructors, inductive type families, sorts and primitive
integers.  Parsing functions may not return terms containing
axioms, bare (co)fixpoints, lambdas, etc.

\end{fulllineitems}\end{savenotes}

\index{Unexpected non\sphinxhyphen{}option term ‘term’ while parsing a string notation (error)@\spxentry{Unexpected non\sphinxhyphen{}option term ‘term’ while parsing a string notation}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Unexpected-non-option-term-_u2018term_u2019-while-parsing-a-string-notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unexpected~non\sphinxhyphen{}option~term~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~while~parsing~a~string~notation.}}}}
\sphinxAtStartPar
Parsing functions expected to return an \sphinxcode{\sphinxupquote{\DUrole{name}{option}}} must always
return a concrete \sphinxcode{\sphinxupquote{\DUrole{name}{Some}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{None}}} when applied to a
concrete string expressed as a decimal.  They may not return
opaque constants.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Number or string notations for parameterized inductive types can be
added by declaring an {\hyperref[\detokenize{user-extensions/syntax-extensions:abbreviations}]{\sphinxcrossref{\DUrole{std,std-ref}{abbreviation}}}} for the
inductive which instantiates all parameters. See {\hyperref[\detokenize{user-extensions/syntax-extensions:example-string-notation-parameterized-inductive}]{\sphinxcrossref{\DUrole{std,std-ref}{example below}}}}.
\end{sphinxadmonition}

\sphinxAtStartPar
The following errors apply to both string and number notations:
\begin{quote}
\index{‘type’ is not an inductive type (error)@\spxentry{‘type’ is not an inductive type}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn._u2018type_u2019-is-not-an-inductive-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~is~not~an~inductive~type.}}}}
\sphinxAtStartPar
String and number notations can only be declared for inductive types.
Declare string or numeral notations for non\sphinxhyphen{}inductive types using \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-number_string_via}]{\sphinxcrossref{\DUrole{hole}{number\_string\_via}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{‘qualid’ was already mapped to ‘qualid’ and cannot be remapped to ‘qualid’ (error)@\spxentry{‘qualid’ was already mapped to ‘qualid’ and cannot be remapped to ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn._u2018qualid_u2019-was-already-mapped-to-_u2018qualid_u2019-and-cannot-be-remapped-to-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~was~already~mapped~to~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~and~cannot~be~remapped~to~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Duplicates are not allowed in the \sphinxcode{\sphinxupquote{\DUrole{notation}{mapping}}} list.

\end{fulllineitems}\end{savenotes}

\index{Missing mapping for constructor ‘qualid’ (error)@\spxentry{Missing mapping for constructor ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Missing-mapping-for-constructor-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Missing~mapping~for~constructor~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
A mapping should be provided for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} in the \sphinxcode{\sphinxupquote{\DUrole{notation}{mapping}}} list.

\end{fulllineitems}\end{savenotes}

\index{‘type’ was already mapped to ‘type’, mapping it also to ‘type’ might yield ill typed terms when using the notation (warning)@\spxentry{‘type’ was already mapped to ‘type’, mapping it also to ‘type’ might yield ill typed terms when using the notation}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:warn._u2018type_u2019-was-already-mapped-to-_u2018type_u2019,-mapping-it-also-to-_u2018type_u2019-might-yield-ill-typed-terms-when-using-the-notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~was~already~mapped~to~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}},~mapping~it~also~to~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~might~yield~ill~typed~terms~when~using~the~notation.}}}}
\sphinxAtStartPar
Two pairs in the \sphinxcode{\sphinxupquote{\DUrole{notation}{mapping}}} list associate types that might be incompatible.

\end{fulllineitems}\end{savenotes}

\index{Type of ‘qualid’ seems incompatible with the type of ‘qualid’. Expected type is: ‘type’ instead of ‘type’. This might yield ill typed terms when using the notation (warning)@\spxentry{Type of ‘qualid’ seems incompatible with the type of ‘qualid’. Expected type is: ‘type’ instead of ‘type’. This might yield ill typed terms when using the notation}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:warn.Type-of-_u2018qualid_u2019-seems-incompatible-with-the-type-of-_u2018qualid_u2019.-Expected-type-is:-_u2018type_u2019-instead-of-_u2018type_u2019.-This-might-yield-ill-typed-terms-when-using-the-notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Type~of~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~seems~incompatible~with~the~type~of~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.~Expected~type~is:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~instead~of~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}.~This~might~yield~ill~typed~terms~when~using~the~notation.}}}}
\sphinxAtStartPar
A mapping given in the \sphinxcode{\sphinxupquote{\DUrole{notation}{mapping}}} list associates a constant with a seemingly incompatible constructor.

\end{fulllineitems}\end{savenotes}

\index{Cannot interpret in ‘scope\_name’ because ‘qualid’ could not be found in the current environment (error)@\spxentry{Cannot interpret in ‘scope\_name’ because ‘qualid’ could not be found in the current environment}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Cannot-interpret-in-_u2018scope_name_u2019-because-_u2018qualid_u2019-could-not-be-found-in-the-current-environment}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~interpret~in~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_name}]{\sphinxcrossref{\DUrole{hole}{scope\_name}}}}~because~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~could~not~be~found~in~the~current~environment.}}}}
\sphinxAtStartPar
The inductive type used to register the string or number notation is no
longer available in the environment.  Most likely, this is because
the notation was declared inside a functor for an
inductive type inside the functor.  This use case is not currently
supported.

\sphinxAtStartPar
Alternatively, you might be trying to use a primitive token
notation from a plugin which forgot to specify which module you
must \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Require}}} for access to that notation.

\end{fulllineitems}\end{savenotes}

\index{Syntax error: {[}prim:reference{]} expected after 'Notation' (in {[}vernac:command{]}) (error)@\spxentry{Syntax error: {[}prim:reference{]} expected after 'Notation' (in {[}vernac:command{]})}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Syntax-error:-_prim:reference_-expected-after-'Notation'-(in-_vernac:command_)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Syntax~error:~{[}prim:reference{]}~expected~after~\textquotesingle{}Notation\textquotesingle{}~(in~{[}vernac:command{]}).}}}}
\sphinxAtStartPar
The type passed to {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}} or {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} must be a single qualified
identifier.

\end{fulllineitems}\end{savenotes}

\index{Syntax error: {[}prim:reference{]} expected after {[}prim:reference{]} (in {[}vernac:command{]}) (error)@\spxentry{Syntax error: {[}prim:reference{]} expected after {[}prim:reference{]} (in {[}vernac:command{]})}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn.Syntax-error:-_prim:reference_-expected-after-_prim:reference_-(in-_vernac:command_)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Syntax~error:~{[}prim:reference{]}~expected~after~{[}prim:reference{]}~(in~{[}vernac:command{]}).}}}}
\sphinxAtStartPar
Both functions passed to {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}} or {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} must be single qualified
identifiers.

\end{fulllineitems}\end{savenotes}

\index{‘qualid’ is bound to a notation that does not denote a reference (error)@\spxentry{‘qualid’ is bound to a notation that does not denote a reference}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:exn._u2018qualid_u2019-is-bound-to-a-notation-that-does-not-denote-a-reference}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~bound~to~a~notation~that~does~not~denote~a~reference.}}}}
\sphinxAtStartPar
Identifiers passed to {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}} or {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} must be global
references, or notations which evaluate to single qualified identifiers.

\end{fulllineitems}\end{savenotes}

\end{quote}

\begin{sphinxadmonition}{note}{Example: Number Notation for radix 3}

\sphinxAtStartPar
The following example parses and prints natural numbers
whose digits are \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{0}}}, \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{1}}} or \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{2}}} as terms of the following
inductive type encoding radix 3 numbers.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{radix3} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
  \PYG{o}{|} \PYG{n}{x0} \PYG{o}{:} \PYG{n}{radix3}
  \PYG{o}{|} \PYG{n}{x3} \PYG{o}{:} \PYG{n}{radix3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{radix3}
  \PYG{o}{|} \PYG{n}{x3p1} \PYG{o}{:} \PYG{n}{radix3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{radix3}
  \PYG{o}{|} \PYG{n}{x3p2} \PYG{o}{:} \PYG{n}{radix3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{radix3}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
We first define a parsing function

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{of\PYGZus{}uint\PYGZus{}dec} \PYG{o}{(}\PYG{n}{u} \PYG{o}{:} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{uint}\PYG{o}{)} \PYG{o}{:} \PYG{n}{option} \PYG{n}{radix3} \PYG{o}{:=}
  \PYG{k}{let} \PYG{k}{fix} \PYG{n}{f} \PYG{n}{u} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{u} \PYG{k}{with}
    \PYG{o}{|} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{Nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{Some} \PYG{n}{x0}
    \PYG{o}{|} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{D0} \PYG{n}{u} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{f} \PYG{n}{u} \PYG{k}{with} \PYG{n}{Some} \PYG{n}{u} \PYG{o}{=\PYGZgt{}} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{x3} \PYG{n}{u}\PYG{o}{)} \PYG{o}{|} \PYG{n}{None} \PYG{o}{=\PYGZgt{}} \PYG{n}{None} \PYG{k}{end}
    \PYG{o}{|} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{D1} \PYG{n}{u} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{f} \PYG{n}{u} \PYG{k}{with} \PYG{n}{Some} \PYG{n}{u} \PYG{o}{=\PYGZgt{}} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{x3p1} \PYG{n}{u}\PYG{o}{)} \PYG{o}{|} \PYG{n}{None} \PYG{o}{=\PYGZgt{}} \PYG{n}{None} \PYG{k}{end}
    \PYG{o}{|} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{D2} \PYG{n}{u} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{f} \PYG{n}{u} \PYG{k}{with} \PYG{n}{Some} \PYG{n}{u} \PYG{o}{=\PYGZgt{}} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{x3p2} \PYG{n}{u}\PYG{o}{)} \PYG{o}{|} \PYG{n}{None} \PYG{o}{=\PYGZgt{}} \PYG{n}{None} \PYG{k}{end}
    \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{None} \PYG{k}{end} \PYG{k}{in}
  \PYG{n}{f} \PYG{o}{(}\PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{rev} \PYG{n}{u}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{of\PYGZus{}uint} \PYG{o}{(}\PYG{n}{u} \PYG{o}{:} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{uint}\PYG{o}{)} \PYG{o}{:} \PYG{n}{option} \PYG{n}{radix3} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{u} \PYG{k}{with} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{UIntDecimal} \PYG{n}{u} \PYG{o}{=\PYGZgt{}} \PYG{n}{of\PYGZus{}uint\PYGZus{}dec} \PYG{n}{u} \PYG{o}{|} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{UIntHexadecimal} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{None} \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
and a printing function

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{to\PYGZus{}uint\PYGZus{}dec} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{radix3}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{uint} \PYG{o}{:=}
  \PYG{k}{let} \PYG{k}{fix} \PYG{n}{f} \PYG{n}{x} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
    \PYG{o}{|} \PYG{n}{x0} \PYG{o}{=\PYGZgt{}} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{Nil}
    \PYG{o}{|} \PYG{n}{x3} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{D0} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)}
    \PYG{o}{|} \PYG{n}{x3p1} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{D1} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)}
    \PYG{o}{|} \PYG{n}{x3p2} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{D2} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)} \PYG{k}{end} \PYG{k}{in}
  \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{rev} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{to\PYGZus{}uint} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{radix3}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{uint} \PYG{o}{:=} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{UIntDecimal} \PYG{o}{(}\PYG{n}{to\PYGZus{}uint\PYGZus{}dec} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
before declaring the notation

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Declare} \PYG{k+kn}{Scope} \PYG{n}{radix3\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{radix3\PYGZus{}scope}\PYG{o}{.}
\PYG{n}{Number} \PYG{k+kn}{Notation} \PYG{n}{radix3} \PYG{n}{of\PYGZus{}uint} \PYG{n}{to\PYGZus{}uint} \PYG{o}{:} \PYG{n}{radix3\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
We can check the printer

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{x3p2} \PYG{o}{(}\PYG{n}{x3p1} \PYG{n}{x0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{12}
         \PYG{o}{:} \PYG{n}{radix3}
\end{sphinxVerbatim}

\sphinxAtStartPar
and the parser

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{k+kn}{All}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{l+m+mi}{120}\PYG{o}{.}
    \PYG{n}{x3} \PYG{o}{(}\PYG{n}{x3p2} \PYG{o}{(}\PYG{n}{x3p1} \PYG{n}{x0}\PYG{o}{)}\PYG{o}{)}
         \PYG{o}{:} \PYG{n}{radix3}
\end{sphinxVerbatim}

\sphinxAtStartPar
Digits other than \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{0}}}, \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{1}}} and \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{2}}} are rejected.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{6}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{7}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Check} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}       \PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{n}{Cannot} \PYG{n}{interpret} \PYG{n}{this} \PYG{n}{number} \PYG{k}{as} \PYG{n}{a} \PYG{n}{value} \PYG{k}{of} \PYG{n}{type} \PYG{n}{radix3}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:example-number-notation-primitive-int}}
\begin{sphinxadmonition}{note}{Example: Number Notation for primitive integers}

\sphinxAtStartPar
This shows the use of the primitive
integers \sphinxcode{\sphinxupquote{\DUrole{notation}{PrimInt63.int}}} as \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{type}}$}}}}}}}. It is the way
parsing and printing of primitive integers are actually implemented
in \sphinxcode{\sphinxupquote{PrimInt63.v}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{PrimInt63}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{parser} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{pos\PYGZus{}neg\PYGZus{}int63}\PYG{o}{)} \PYG{o}{:} \PYG{n}{option} \PYG{n}{int} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{x} \PYG{k}{with} \PYG{n}{Pos} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{Some} \PYG{n}{p} \PYG{o}{|} \PYG{n}{Neg} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{None} \PYG{k}{end}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{printer} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{int\PYGZus{}wrapper}\PYG{o}{)} \PYG{o}{:} \PYG{n}{pos\PYGZus{}neg\PYGZus{}int63} \PYG{o}{:=} \PYG{n}{Pos} \PYG{o}{(}\PYG{n}{int\PYGZus{}wrap} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{Number} \PYG{k+kn}{Notation} \PYG{n}{int} \PYG{n}{parser} \PYG{n}{printer} \PYG{o}{:} \PYG{n}{uint63\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:example-number-notation-non-inductive}}
\begin{sphinxadmonition}{note}{Example: Number Notation for a non inductive type}

\sphinxAtStartPar
The following example encodes the terms in the form \sphinxcode{\sphinxupquote{\DUrole{name}{sum} \DUrole{name}{unit} \DUrole{operator}{(} \DUrole{operator}{...} \DUrole{operator}{(}\DUrole{name}{sum} \DUrole{name}{unit} \DUrole{name}{unit}\DUrole{operator}{)} \DUrole{operator}{...} \DUrole{operator}{)}}}
as the number of units in the term. For instance \sphinxcode{\sphinxupquote{\DUrole{name}{sum} \DUrole{name}{unit} \DUrole{operator}{(}\DUrole{name}{sum} \DUrole{name}{unit} \DUrole{name}{unit}\DUrole{operator}{)}}}
is encoded as \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{3}}} while \sphinxcode{\sphinxupquote{\DUrole{name}{unit}}} is \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{1}}} and \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{0}}} stands for \sphinxcode{\sphinxupquote{\DUrole{name}{Empty\_set}}}.
The inductive \sphinxcode{\sphinxupquote{\DUrole{name}{I}}} will be used as \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{ind}}$}}}}}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{I} \PYG{o}{:=} \PYG{n}{Iempty} \PYG{o}{:} \PYG{n}{I} \PYG{o}{|} \PYG{n}{Iunit} \PYG{o}{:} \PYG{n}{I} \PYG{o}{|} \PYG{n}{Isum} \PYG{o}{:} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{I}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
We then define \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{parse}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{print}}$}}}}}}}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{of\PYGZus{}uint} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{uint}\PYG{o}{)} \PYG{o}{:} \PYG{n}{I} \PYG{o}{:=}
  \PYG{k}{let} \PYG{k}{fix} \PYG{n}{f} \PYG{n}{n} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
    \PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{Iempty} \PYG{o}{|} \PYG{n}{S} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{Iunit}
    \PYG{o}{|} \PYG{n}{S} \PYG{n}{n} \PYG{o}{=\PYGZgt{}} \PYG{n}{Isum} \PYG{n}{Iunit} \PYG{o}{(}\PYG{n}{f} \PYG{n}{n}\PYG{o}{)} \PYG{k}{end} \PYG{k}{in}
  \PYG{n}{f} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{of\PYGZus{}num\PYGZus{}uint} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}

\PYG{k+kn}{Definition} \PYG{n}{to\PYGZus{}uint} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{I}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{uint} \PYG{o}{:=}
  \PYG{k}{let} \PYG{k}{fix} \PYG{n}{f} \PYG{n}{i} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{i} \PYG{k}{with}
    \PYG{o}{|} \PYG{n}{Iempty} \PYG{o}{=\PYGZgt{}} \PYG{n}{O} \PYG{o}{|} \PYG{n}{Iunit} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{1}
    \PYG{o}{|} \PYG{n}{Isum} \PYG{n}{i1} \PYG{n}{i2} \PYG{o}{=\PYGZgt{}} \PYG{n}{f} \PYG{n}{i1} \PYG{o}{+} \PYG{n}{f} \PYG{n}{i2} \PYG{k}{end} \PYG{k}{in}
  \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{to\PYGZus{}num\PYGZus{}uint} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}

\PYG{k+kn}{Inductive} \PYG{n}{sum} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\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{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{sum} \PYG{n}{A} \PYG{n}{B}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
the number notation itself

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{n}{nSet} \PYG{o}{:=} \PYG{k+kn}{Set} \PYG{o}{(}\PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{Number} \PYG{k+kn}{Notation} \PYG{n}{nSet} \PYG{n}{of\PYGZus{}uint} \PYG{n}{to\PYGZus{}uint} \PYG{o}{(}\PYG{n}{via} \PYG{n}{I}
  \PYG{n}{mapping} \PYG{o}{[}\PYG{n}{Empty\PYGZus{}set} \PYG{o}{=\PYGZgt{}} \PYG{n}{Iempty}\PYG{o}{,} \PYG{n}{unit} \PYG{o}{=\PYGZgt{}} \PYG{n}{Iunit}\PYG{o}{,} \PYG{n}{sum} \PYG{o}{=\PYGZgt{}} \PYG{n}{Isum}\PYG{o}{]}\PYG{o}{)} \PYG{o}{:} \PYG{n}{type\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
and check the printer

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Local} \PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{type\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{sum} \PYG{n}{unit} \PYG{o}{(}\PYG{n}{sum} \PYG{n}{unit} \PYG{n}{unit}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{3}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

\sphinxAtStartPar
and the parser

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{k+kn}{All}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{n}{sum} \PYG{n}{unit} \PYG{o}{(}\PYG{n}{sum} \PYG{n}{unit} \PYG{n}{unit}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:example-number-notation-implicit-args}}
\begin{sphinxadmonition}{note}{Example: Number Notation with implicit arguments}

\sphinxAtStartPar
The following example parses and prints natural numbers between
\sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{0}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{n}\DUrole{operator}{\sphinxhyphen{}}\DUrole{literal,number,integer}{1}}} as terms of type \sphinxcode{\sphinxupquote{\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{t} \DUrole{name}{n}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Vector}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t}\PYG{o}{.}
    \PYG{k+kn}{Inductive} \PYG{n}{t} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
        \PYG{n}{F1} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}
      \PYG{o}{|} \PYG{n}{FS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
    
    \PYG{k+kn}{Arguments} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}
    \PYG{k+kn}{Arguments} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{F1} \PYG{o}{\PYGZob{}}\PYG{n}{n}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}
    \PYG{k+kn}{Arguments} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{FS} \PYG{o}{\PYGZob{}}\PYG{n}{n}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope} \PYG{o}{\PYGZus{}}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note the implicit arguments of \sphinxcode{\sphinxupquote{\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{F1}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{FS}}},
which won't appear in the corresponding inductive type.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{I} \PYG{o}{:=} \PYG{n}{I1} \PYG{o}{:} \PYG{n}{I} \PYG{o}{|} \PYG{n}{IS} \PYG{o}{:} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{I}\PYG{o}{.}

\PYG{k+kn}{Definition} \PYG{n}{of\PYGZus{}uint} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{uint}\PYG{o}{)} \PYG{o}{:} \PYG{n}{I} \PYG{o}{:=}
  \PYG{k}{let} \PYG{k}{fix} \PYG{n}{f} \PYG{n}{n} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{n} \PYG{k}{with} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{I1} \PYG{o}{|} \PYG{n}{S} \PYG{n}{n} \PYG{o}{=\PYGZgt{}} \PYG{n}{IS} \PYG{o}{(}\PYG{n}{f} \PYG{n}{n}\PYG{o}{)} \PYG{k}{end} \PYG{k}{in}
  \PYG{n}{f} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{of\PYGZus{}num\PYGZus{}uint} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}

\PYG{k+kn}{Definition} \PYG{n}{to\PYGZus{}uint} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{I}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{uint} \PYG{o}{:=}
  \PYG{k}{let} \PYG{k}{fix} \PYG{n}{f} \PYG{n}{i} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{i} \PYG{k}{with} \PYG{n}{I1} \PYG{o}{=\PYGZgt{}} \PYG{n}{O} \PYG{o}{|} \PYG{n}{IS} \PYG{n}{n} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{f} \PYG{n}{n}\PYG{o}{)} \PYG{k}{end} \PYG{k}{in}
  \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{to\PYGZus{}num\PYGZus{}uint} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}

\PYG{n}{Declare} \PYG{k+kn}{Scope} \PYG{n}{fin\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Delimit} \PYG{k+kn}{Scope} \PYG{n}{fin\PYGZus{}scope} \PYG{k}{with} \PYG{n}{fin}\PYG{o}{.}
\PYG{k+kn}{Local} \PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{fin\PYGZus{}scope}\PYG{o}{.}
\PYG{n}{Number} \PYG{k+kn}{Notation} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{n}{of\PYGZus{}uint} \PYG{n}{to\PYGZus{}uint} \PYG{o}{(}\PYG{n}{via} \PYG{n}{I}
  \PYG{n}{mapping} \PYG{o}{[}\PYG{o}{[}\PYG{n}{Fin}\PYG{o}{.}\PYG{n}{F1}\PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{n}{I1}\PYG{o}{,} \PYG{o}{[}\PYG{n}{Fin}\PYG{o}{.}\PYG{n}{FS}\PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{n}{IS}\PYG{o}{]}\PYG{o}{)} \PYG{o}{:} \PYG{n}{fin\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Now \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{2}}} is parsed as \sphinxcode{\sphinxupquote{\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{FS} \DUrole{operator}{(}\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{FS} \DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{F1}\DUrole{operator}{)}}}, that is
\sphinxcode{\sphinxupquote{\DUrole{operator}{@}\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{FS} \DUrole{operator}{\_} \DUrole{operator}{(@}\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{FS} \DUrole{operator}{\_} \DUrole{operator}{(@}\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{F1} \DUrole{operator}{\_))}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{2}
         \PYG{o}{:} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{o}{?}\PYG{n}{n}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{n} \PYG{o}{:} \PYG{o}{[} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{n}{nat}\PYG{o}{]}
\end{sphinxVerbatim}

\sphinxAtStartPar
which can be of type \sphinxcode{\sphinxupquote{\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{t} \DUrole{literal,number,integer}{3}}} (numbers \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{0}}}, \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{1}}} and \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{2}}})

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{l+m+mi}{3}
         \PYG{o}{:} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{l+m+mi}{3}
\end{sphinxVerbatim}

\sphinxAtStartPar
but cannot be of type \sphinxcode{\sphinxupquote{\DUrole{name}{Fin}\DUrole{operator}{.}\DUrole{name}{t} \DUrole{literal,number,integer}{2}}} (only \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{0}}} and \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{1}}})

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{6}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{7}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Check} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{n}{Fin}\PYG{o}{.}\PYG{n}{t} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}       \PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{2}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Fin.t (S (S (S ?n)))}\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}{Fin.t 2}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:example-string-notation-parameterized-inductive}}
\begin{sphinxadmonition}{note}{Example: String Notation with a parameterized inductive type}

\sphinxAtStartPar
The parameter \sphinxcode{\sphinxupquote{\DUrole{name}{Byte}\DUrole{operator}{.}\DUrole{name}{byte}}} for the parameterized inductive type
\sphinxcode{\sphinxupquote{\DUrole{name}{list}}} is given through an {\hyperref[\detokenize{user-extensions/syntax-extensions:abbreviations}]{\sphinxcrossref{\DUrole{std,std-ref}{abbreviation}}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{n}{string} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{list} \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{byte}\PYG{o}{)} \PYG{o}{(}\PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{id\PYGZus{}string} \PYG{o}{:=} \PYG{o}{@}\PYG{n}{id} \PYG{n}{string}\PYG{o}{.}

\PYG{n}{String} \PYG{k+kn}{Notation} \PYG{n}{string} \PYG{n}{id\PYGZus{}string} \PYG{n}{id\PYGZus{}string} \PYG{o}{:} \PYG{n}{list\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{abc}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{\PYGZpc{}}\PYG{n}{list}\PYG{o}{.}
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{abc}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{\PYGZpc{}}\PYG{n}{list}
         \PYG{o}{:} \PYG{n}{list} \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{byte}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Tactic Notations}
\label{\detokenize{user-extensions/syntax-extensions:tactic-notations}}\label{\detokenize{user-extensions/syntax-extensions:tacticnotation}}
\sphinxAtStartPar
Tactic notations allow customizing the syntax of tactics.
\index{Tactic Notation (command)@\spxentry{Tactic Notation}\spxextra{command}}

\begin{savenotes}\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~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~)}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-ltac_production_item}]{\sphinxcrossref{\DUrole{hole}{ltac\_production\_item}}}}}\DUrole{notation-sup}{+}}~:=~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-ltac_production_item}}}\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-ltac_production_item}]{\sphinxcrossref{\DUrole{hole}{ltac\_production\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{( {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{, {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}} )}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Defines a \sphinxstyleemphasis{tactic notation}, which extends the parsing and pretty\sphinxhyphen{}printing of tactics.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which limits the notation to the
current module.
\begin{quote}
\begin{description}
\item[{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}}] \leavevmode
\sphinxAtStartPar
The parsing precedence to assign to the notation.  This information is particularly
relevant for notations for tacticals.  Levels can be in the range 0 .. 5 (default is 5).

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-ltac_production_item}]{\sphinxcrossref{\DUrole{hole}{ltac\_production\_item}}}}}\DUrole{notation-sup}{+}}}}}}] \leavevmode
\sphinxAtStartPar
The notation syntax.  Notations for simple tactics should begin with a {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}.
Note that \sphinxcode{\sphinxupquote{Tactic Notation foo := idtac}} is not valid; it should be \sphinxcode{\sphinxupquote{Tactic Notation "foo" := idtac}}.

\item[{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}}] \leavevmode
\sphinxAtStartPar
represents a literal value in the notation

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
is the name of a grammar nonterminal listed in the table below.  In a few cases,
to maintain backward compatibility, the name differs from the nonterminal name
used elsewhere in the documentation.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{( {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{parm}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{, {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{s}}$}}}}}\DUrole{notation-sup}{?}} )}}}}] \leavevmode
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{parm}}$}}}}}}} is the parameter name associated with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.   The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{s}}$}}}}}}}
is the separator string to use when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} specifies a list with separators
(i.e. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} ends with \sphinxcode{\sphinxupquote{\_list\_sep}}).

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}] \leavevmode
\sphinxAtStartPar
The tactic expression to substitute for the notation.  \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{parm}}$}}}}}}}
tokens appearing in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} are substituted with the associated
nonterminal value.

\end{description}
\end{quote}

\sphinxAtStartPar
For example, the following command defines a notation with a single parameter \sphinxcode{\sphinxupquote{x}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Tactic} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{destruct\PYGZus{}with\PYGZus{}eqn}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{constr}\PYG{o}{(}\PYG{n}{x}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{destruct} \PYG{n}{x} \PYG{n}{eqn}\PYG{o}{:}\PYG{o}{?}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
For a complex example, examine the 16 \sphinxcode{\sphinxupquote{Tactic Notation "setoid\_replace"}}s
defined in \sphinxcode{\sphinxupquote{\$COQLIB/theories/Classes/SetoidTactics.v}}, which are designed
to accept any subset of 4 optional parameters.

\sphinxAtStartPar
The nonterminals that can specified in the tactic notation are:
\begin{quote}
\end{quote}


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
Specified {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Parsed as
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Interpreted as
&\sphinxstyletheadfamily 
\sphinxAtStartPar
as in tactic
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ident}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
&
\sphinxAtStartPar
a user\sphinxhyphen{}given name
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{simple\_intropattern}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_intropattern}}}}}
&
\sphinxAtStartPar
an introduction pattern
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert}}}}} \sphinxcode{\sphinxupquote{as}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{hyp}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
&
\sphinxAtStartPar
a hypothesis defined in context
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.clear}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{reference}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}
&
\sphinxAtStartPar
a qualified identifier
&
\sphinxAtStartPar
name of an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$\sphinxhyphen{}defined tactic
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{smart\_global}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}}
&
\sphinxAtStartPar
a global reference of term
&
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.with_strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{with\_strategy}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{constr}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}
&
\sphinxAtStartPar
a term
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{uconstr}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}
&
\sphinxAtStartPar
an untyped term
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{integer}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}
&
\sphinxAtStartPar
an integer
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{int\_or\_var}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:grammar-token-int_or_var}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{int\_or\_var}}}}}
&
\sphinxAtStartPar
an integer
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.do}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{do}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{strategy\_level}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{strategy\_level}}}}}
&
\sphinxAtStartPar
a strategy level
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{strategy\_level\_or\_var}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level_or_var}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{strategy\_level\_or\_var}}}}}
&
\sphinxAtStartPar
a strategy level
&
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.with_strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{with\_strategy}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{tactic}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}
&
\sphinxAtStartPar
a tactic
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{tactic}}\sphinxstyleemphasis{n} (\sphinxstyleemphasis{n} in 0..5)
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}\sphinxstyleemphasis{n}
&
\sphinxAtStartPar
a tactic at level \sphinxstyleemphasis{n}
&\\
\hline
\sphinxAtStartPar
\sphinxstyleemphasis{entry}\sphinxcode{\sphinxupquote{\_list}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{entry}\DUrole{notation-sup}{*}}}}}
&
\sphinxAtStartPar
a list of how \sphinxstyleemphasis{entry} is interpreted
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ne\_}}\sphinxstyleemphasis{entry}\sphinxcode{\sphinxupquote{\_list}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{entry}\DUrole{notation-sup}{+}}}}}
&
\sphinxAtStartPar
a list of how \sphinxstyleemphasis{entry} is interpreted
&\\
\hline
\sphinxAtStartPar
\sphinxstyleemphasis{entry}\sphinxcode{\sphinxupquote{\_list\_sep}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{entry}\DUrole{notation-sup}{*}\DUrole{notation-sub}{s}}}}}
&
\sphinxAtStartPar
a list of how \sphinxstyleemphasis{entry} is interpreted
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ne\_}}\sphinxstyleemphasis{entry}\sphinxcode{\sphinxupquote{\_list\_sep}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{entry}\DUrole{notation-sup}{+}\DUrole{notation-sub}{s}}}}}
&
\sphinxAtStartPar
a list of how \sphinxstyleemphasis{entry} is interpreted
&\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
In order to be bound in tactic definitions, each
syntactic entry for argument type must include the case
of a simple \sphinxcode{\sphinxupquote{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}} nor for \sphinxcode{\sphinxupquote{strategy\_level}}.  This
is the reason for introducing special entries
\sphinxcode{\sphinxupquote{int\_or\_var}} and \sphinxcode{\sphinxupquote{strategy\_level\_or\_var}} which
evaluate to integers or strategy levels only,
respectively, but which syntactically includes
identifiers in order to be usable in tactic definitions.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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}}, \sphinxcode{\sphinxupquote{reference}}, \sphinxcode{\sphinxupquote{strategy\_level}},
\sphinxcode{\sphinxupquote{strategy\_level\_or\_var}}, or \sphinxcode{\sphinxupquote{int\_or\_var}}.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\subsection{Setting properties of a function's arguments}
\label{\detokenize{language/extensions/arguments-command:setting-properties-of-a-function-s-arguments}}\label{\detokenize{language/extensions/arguments-command:argumentscommand}}\label{\detokenize{language/extensions/arguments-command::doc}}\index{Arguments (command)@\spxentry{Arguments}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-arg_specs}]{\sphinxcrossref{\DUrole{hole}{arg\_specs}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{,~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-implicits_alt}]{\sphinxcrossref{\DUrole{hole}{implicits\_alt}}}}}\DUrole{notation-sup}{*}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-args_modifier}]{\sphinxcrossref{\DUrole{hole}{args\_modifier}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/arguments-command:grammar-token-argument_spec}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-argument_spec}]{\sphinxcrossref{\DUrole{hole}{argument\_spec}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{!}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/arguments-command:grammar-token-arg_specs}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-arg_specs}]{\sphinxcrossref{\DUrole{hole}{arg\_specs}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-argument_spec}]{\sphinxcrossref{\DUrole{hole}{argument\_spec}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{/}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\&}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-argument_spec}]{\sphinxcrossref{\DUrole{hole}{argument\_spec}}}}}\DUrole{notation-sup}{+}} ) \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-argument_spec}]{\sphinxcrossref{\DUrole{hole}{argument\_spec}}}}}\DUrole{notation-sup}{+}} {]} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-argument_spec}]{\sphinxcrossref{\DUrole{hole}{argument\_spec}}}}}\DUrole{notation-sup}{+}} \} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/arguments-command:grammar-token-implicits_alt}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-implicits_alt}]{\sphinxcrossref{\DUrole{hole}{implicits\_alt}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{language/extensions/arguments-command:grammar-token-args_modifier}}}\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-args_modifier}]{\sphinxcrossref{\DUrole{hole}{args\_modifier}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{simpl nomatch}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{simpl never}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{default implicits}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{clear implicits}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{clear scopes}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{clear bidirectionality hint}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{rename}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{assert}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{extra scopes}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{clear scopes and implicits}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{clear implicits and scopes}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Specifies properties of the arguments of a function after the function has already
been defined.  It gives fine\sphinxhyphen{}grained
control over the elaboration process (i.e. the translation of Gallina language
extensions into the core language used by the kernel).  The command's effects include:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Making arguments implicit. Afterward, implicit arguments
must be omitted in any expression that applies {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}}.

\item {} 
\sphinxAtStartPar
Declaring that some arguments of a given function should
be interpreted in a given scope.

\item {} 
\sphinxAtStartPar
Affecting when the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}} tactics unfold the function.
See {\hyperref[\detokenize{language/extensions/arguments-command:args-effect-on-unfolding}]{\sphinxcrossref{\DUrole{std,std-ref}{Effects of Arguments on unfolding}}}}.

\item {} 
\sphinxAtStartPar
Providing bidirectionality hints.  See {\hyperref[\detokenize{language/extensions/arguments-command:bidirectionality-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Bidirectionality hints}}}}.

\end{itemize}

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} and {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attributes.
Default behavior is to limit the effect to the current section but also to
extend their effect outside the current module or library file.
Applying {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} limits the effect of the command to the current module if
it's not in a section.  Applying {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} within a section extends the
effect outside the current sections and current module in which the command appears.
\begin{quote}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{/}}}] \leavevmode
\sphinxAtStartPar
the function will be unfolded only if it's applied to at least the
arguments appearing before the \sphinxcode{\sphinxupquote{/}}.  See {\hyperref[\detokenize{language/extensions/arguments-command:args-effect-on-unfolding}]{\sphinxcrossref{\DUrole{std,std-ref}{Effects of Arguments on unfolding}}}}.
\index{The / modifier may only occur once (error)@\spxentry{The / modifier may only occur once}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/arguments-command:coq:exn.The-/-modifier-may-only-occur-once}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~/~modifier~may~only~occur~once.}}}}
\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{\&}}}] \leavevmode
\sphinxAtStartPar
tells the type checking algorithm to first type check the arguments
before the \sphinxcode{\sphinxupquote{\&}} and then to propagate information from that typing context
to type check the remaining arguments. See {\hyperref[\detokenize{language/extensions/arguments-command:bidirectionality-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Bidirectionality hints}}}}.
\index{The \& modifier may only occur once (error)@\spxentry{The \& modifier may only occur once}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/arguments-command:coq:exn.The-_-modifier-may-only-occur-once}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~\&~modifier~may~only~occur~once.}}}}
\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{( ... ) \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{2}}$}}}} ...)\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}} is shorthand for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{1}}$}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{2}}$}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}} ...}}}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} ... {]} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
declares the enclosed names as implicit, non\sphinxhyphen{}maximally inserted.
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{2}}$}}}} ... {]}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{1}}$}}}}{]}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}} {[}{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{2}}$}}}}{]}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}} ...}}}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\{ ... \} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
declares the enclosed names as implicit, maximally inserted.
\sphinxcode{\sphinxupquote{\DUrole{notation}{\{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{2}}$}}}} ... \}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{\{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{1}}$}}}}\}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}} \{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name$_{\text{2}}$}}}}\}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}} ...}}}

\item[{\sphinxcode{\sphinxupquote{!}}}] \leavevmode
\sphinxAtStartPar
the function will be unfolded only if all the arguments marked with \sphinxcode{\sphinxupquote{!}}
evaluate to constructors.  See {\hyperref[\detokenize{language/extensions/arguments-command:args-effect-on-unfolding}]{\sphinxcrossref{\DUrole{std,std-ref}{Effects of Arguments on unfolding}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
a \sphinxstyleemphasis{formal parameter} of the function \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} (i.e.
the parameter name used in the function definition).  Unless \sphinxcode{\sphinxupquote{rename}} is specified,
the list of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}}s must be a prefix of the formal parameters, including all implicit
arguments.  \sphinxcode{\sphinxupquote{\_}} can be used to skip over a formal parameter.
The construct \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{?}}}}} declares \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}} as non\sphinxhyphen{}implicit if \sphinxcode{\sphinxupquote{clear implicits}} is specified or at least one other name is declared implicit in the same list of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}}s.
{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}} can be either a scope name or its delimiting key.  See {\hyperref[\detokenize{language/extensions/arguments-command:binding-to-scope}]{\sphinxcrossref{\DUrole{std,std-ref}{Binding arguments to a scope}}}}.
\index{To rename arguments the 'rename' flag must be specified (error)@\spxentry{To rename arguments the 'rename' flag must be specified}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/arguments-command:coq:exn.To-rename-arguments-the-'rename'-flag-must-be-specified}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{To~rename~arguments~the~\textquotesingle{}rename\textquotesingle{}~flag~must~be~specified.}}}}
\end{fulllineitems}\end{savenotes}

\index{Flag 'rename' expected to rename ‘name’ into ‘name’ (error)@\spxentry{Flag 'rename' expected to rename ‘name’ into ‘name’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/arguments-command:coq:exn.Flag-'rename'-expected-to-rename-_u2018name_u2019-into-_u2018name_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Flag~\textquotesingle{}rename\textquotesingle{}~expected~to~rename~{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}~into~{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}.}}}}
\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{clear implicits}}}] \leavevmode
\sphinxAtStartPar
makes all implicit arguments into explicit arguments
\index{The 'clear implicits' flag must be omitted if implicit annotations are given (error)@\spxentry{The 'clear implicits' flag must be omitted if implicit annotations are given}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/arguments-command:coq:exn.The-'clear-implicits'-flag-must-be-omitted-if-implicit-annotations-are-given}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~\textquotesingle{}clear~implicits\textquotesingle{}~flag~must~be~omitted~if~implicit~annotations~are~given.}}}}
\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{default implicits}}}] \leavevmode
\sphinxAtStartPar
automatically determine the implicit arguments of the object.
See {\hyperref[\detokenize{language/extensions/arguments-command:auto-decl-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Automatic declaration of implicit arguments}}}}.
\index{The 'default implicits' flag is incompatible with implicit annotations (error)@\spxentry{The 'default implicits' flag is incompatible with implicit annotations}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/arguments-command:coq:exn.The-'default-implicits'-flag-is-incompatible-with-implicit-annotations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~\textquotesingle{}default~implicits\textquotesingle{}~flag~is~incompatible~with~implicit~annotations.}}}}
\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{rename}}}] \leavevmode
\sphinxAtStartPar
rename implicit arguments for the object.  See the example {\hyperref[\detokenize{language/extensions/arguments-command:renaming-implicit-arguments}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\item[{\sphinxcode{\sphinxupquote{assert}}}] \leavevmode
\sphinxAtStartPar
assert that the object has the expected number of arguments with the
expected names.  See the example here: {\hyperref[\detokenize{language/extensions/arguments-command:renaming-implicit-arguments}]{\sphinxcrossref{\DUrole{std,std-ref}{Renaming implicit arguments}}}}.
\index{This command is just asserting the names of arguments of ‘qualid’. If this is what you want, add ': assert' to silence the warning. If you want to clear implicit arguments, add ': clear implicits'. If you want to clear notation scopes, add ': clear scopes' (warning)@\spxentry{This command is just asserting the names of arguments of ‘qualid’. If this is what you want, add ': assert' to silence the warning. If you want to clear implicit arguments, add ': clear implicits'. If you want to clear notation scopes, add ': clear scopes'}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/arguments-command:coq:warn.This-command-is-just-asserting-the-names-of-arguments-of-_u2018qualid_u2019.-If-this-is-what-you-want,-add-':-assert'-to-silence-the-warning.-If-you-want-to-clear-implicit-arguments,-add-':-clear-implicits'.-If-you-want-to-clear-notation-scopes,-add-':-clear-scopes'}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{This~command~is~just~asserting~the~names~of~arguments~of~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.~If~this~is~what~you~want,~add~\textquotesingle{}:~assert\textquotesingle{}~to~silence~the~warning.~If~you~want~to~clear~implicit~arguments,~add~\textquotesingle{}:~clear~implicits\textquotesingle{}.~If~you~want~to~clear~notation~scopes,~add~\textquotesingle{}:~clear~scopes\textquotesingle{}}}}}
\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{clear scopes}}}] \leavevmode
\sphinxAtStartPar
clears argument scopes of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}

\item[{\sphinxcode{\sphinxupquote{extra scopes}}}] \leavevmode
\sphinxAtStartPar
defines extra argument scopes, to be used in case of coercion to \sphinxcode{\sphinxupquote{Funclass}}
(see {\hyperref[\detokenize{addendum/implicit-coercions:coercions}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit Coercions}}}}) or with a computed type.

\item[{\sphinxcode{\sphinxupquote{simpl nomatch}}}] \leavevmode
\sphinxAtStartPar
prevents performing a simplification step for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}
that would expose a match construct in the head position.  See {\hyperref[\detokenize{language/extensions/arguments-command:args-effect-on-unfolding}]{\sphinxcrossref{\DUrole{std,std-ref}{Effects of Arguments on unfolding}}}}.

\item[{\sphinxcode{\sphinxupquote{simpl never}}}] \leavevmode
\sphinxAtStartPar
prevents performing a simplification step for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}.  See {\hyperref[\detokenize{language/extensions/arguments-command:args-effect-on-unfolding}]{\sphinxcrossref{\DUrole{std,std-ref}{Effects of Arguments on unfolding}}}}.

\item[{\sphinxcode{\sphinxupquote{clear bidirectionality hint}}}] \leavevmode
\sphinxAtStartPar
removes the bidirectionality hint, the \sphinxcode{\sphinxupquote{\&}}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-implicits_alt}]{\sphinxcrossref{\DUrole{hole}{implicits\_alt}}}}}}}}] \leavevmode
\sphinxAtStartPar
use to specify alternative implicit argument declarations
for functions that can only be
applied to a fixed number of arguments (excluding, for instance,
functions whose type is polymorphic).
For parsing, the longest list of implicit arguments matching the function application
is used to select which implicit arguments are inserted.
For printing, the alternative with the most implicit arguments is used; the
implict arguments will be omitted if {\hyperref[\detokenize{language/extensions/implicit-arguments:coq:flag.Printing-Implicit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Implicit}}}}} is not set.
See the example {\hyperref[\detokenize{language/extensions/arguments-command:example-more-implicits}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\end{description}
\end{quote}

\sphinxAtStartPar
Use {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.About}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{About}}}}} to view the current implicit arguments setting for a {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}}.

\sphinxAtStartPar
Or use the {\hyperref[\detokenize{language/extensions/implicit-arguments:coq:cmd.Print-Implicit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Implicit}}}}} command to see the implicit arguments
of an object (see {\hyperref[\detokenize{language/extensions/implicit-arguments:displaying-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Displaying implicit arguments}}}}).

\end{fulllineitems}\end{savenotes}



\subsubsection{Manual declaration of implicit arguments}
\label{\detokenize{language/extensions/arguments-command:manual-declaration-of-implicit-arguments}}
\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{list} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}
\PYG{o}{|} \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}{.}
    \PYG{n}{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{n}{list\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{nat} \PYG{l+m+mi}{3} \PYG{o}{(}\PYG{n}{nil} \PYG{n}{nat}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{cons} \PYG{n}{nat} \PYG{l+m+mi}{3} \PYG{o}{(}\PYG{n}{nil} \PYG{n}{nat}\PYG{o}{)}
         \PYG{o}{:} \PYG{n}{list} \PYG{n}{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}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\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{n}{list} \PYG{n}{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{n}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{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}{|} \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}{guarded} \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{n}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{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}{|} \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}{guarded} \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{n}{list} \PYG{o}{(}\PYG{n}{list} \PYG{n}{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{n}{list} \PYG{o}{(}\PYG{n}{list} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{map} \PYG{n}{length} \PYG{n}{l}
         \PYG{o}{:} \PYG{n}{list} \PYG{o}{(}\PYG{n}{list} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{language/extensions/arguments-command:example-more-implicits}}
\begin{sphinxadmonition}{note}{Example: Multiple alternatives with \sphinxstyleliteralintitle{\sphinxupquote{implicits\_alt}}}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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{n}{list} \PYG{n}{nat}\PYG{o}{)} \PYG{n}{nat} \PYG{n}{length} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{o}{(}\PYG{n}{list} \PYG{n}{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{n}{list} \PYG{o}{(}\PYG{n}{list} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Automatic declaration of implicit arguments}
\label{\detokenize{language/extensions/arguments-command:automatic-declaration-of-implicit-arguments}}\label{\detokenize{language/extensions/arguments-command:auto-decl-implicit-args}}\begin{quote}

\sphinxAtStartPar
The "\sphinxcode{\sphinxupquote{\DUrole{notation}{default implicits}}}" {\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-args_modifier}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{args\_modifier}}}}} clause tells Coq to automatically determine the
implicit arguments of the object.

\sphinxAtStartPar
Auto\sphinxhyphen{}detection is governed by flags specifying whether strict,
contextual, or reversible\sphinxhyphen{}pattern implicit arguments must be
considered or not (see {\hyperref[\detokenize{language/extensions/implicit-arguments:controlling-strict-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling strict implicit arguments}}}}, {\hyperref[\detokenize{language/extensions/implicit-arguments:controlling-contextual-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling contextual implicit arguments}}}},
{\hyperref[\detokenize{language/extensions/implicit-arguments:controlling-rev-pattern-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reversible\sphinxhyphen{}pattern implicit arguments}}}} and also {\hyperref[\detokenize{language/extensions/implicit-arguments:controlling-insertion-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling the insertion of implicit arguments not followed by explicit arguments}}}}).
\end{quote}

\begin{sphinxadmonition}{note}{Example: Default implicits}

\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}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}
\PYG{o}{|} \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}{.}
    \PYG{n}{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{n}{list\PYGZus{}sind} \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{o}{[}\PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{]}\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{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{n}{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{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{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}

\sphinxAtStartPar
The computation of implicit arguments takes account of the unfolding
of {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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 \sphinxhyphen{}> forall z:U, R y z \sphinxhyphen{}> R x z}}. As the variables \sphinxcode{\sphinxupquote{x}}, \sphinxcode{\sphinxupquote{y}} and \sphinxcode{\sphinxupquote{z}}
appear strictly in the {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} of the type, they are implicit.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \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}{Parameters} \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{o}{[}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{X}\PYG{o}{]}\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}{p} \PYG{o}{[}\PYG{n}{x} \PYG{n}{y}\PYG{o}{]} \PYG{o}{\PYGZus{}} \PYG{o}{[}\PYG{n}{z}\PYG{o}{]} \PYG{o}{\PYGZus{}}


\PYG{k+kn}{Print} \PYG{k+kn}{Implicit} \PYG{n}{p}\PYG{o}{.}
    \PYG{n}{p} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{[}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{X}\PYG{o}{]}\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}{Parameters} \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{Renaming implicit arguments}
\label{\detokenize{language/extensions/arguments-command:renaming-implicit-arguments}}\label{\detokenize{language/extensions/arguments-command:id1}}
\begin{sphinxadmonition}{note}{Example: (continued)  Renaming implicit arguments}

\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}{Flag} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{rename}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{rename} \PYG{n}{u} \PYG{n}{into} \PYG{n}{w}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Binding arguments to a scope}
\label{\detokenize{language/extensions/arguments-command:binding-arguments-to-a-scope}}\label{\detokenize{language/extensions/arguments-command:binding-to-scope}}\begin{quote}

\sphinxAtStartPar
The following command declares that the first two arguments of \sphinxcode{\sphinxupquote{\DUrole{name}{plus\_fct}}}
are in the {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}} delimited by the key \sphinxcode{\sphinxupquote{F}} (\sphinxcode{\sphinxupquote{Rfun\_scope}}) and the third
argument is in the scope delimited by the key \sphinxcode{\sphinxupquote{R}} (\sphinxcode{\sphinxupquote{R\_scope}}).
\begin{quote}

\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}
\end{quote}

\sphinxAtStartPar
When interpreting a term, if some of the arguments of {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}} 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.
\end{quote}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{g} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}\PYG{o}{.}
    \PYG{n}{g} \PYG{k}{is} \PYG{n}{declared}

\PYG{n}{Declare} \PYG{k+kn}{Scope} \PYG{n}{mybool\PYGZus{}scope}\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}{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{n}{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{n}{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{n}{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{n}{bool}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Effects of \sphinxstyleliteralintitle{\sphinxupquote{Arguments}} on unfolding}
\label{\detokenize{language/extensions/arguments-command:effects-of-arguments-on-unfolding}}\label{\detokenize{language/extensions/arguments-command:args-effect-on-unfolding}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{simpl never}} indicates that a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} should never be unfolded by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}},
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}}:

\begin{sphinxadmonition}{note}{Example}

\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}

\sphinxAtStartPar
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 {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}}.

\item {} 
\sphinxAtStartPar
A {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} can be marked to be unfolded only if it's applied to at least
the arguments appearing before the \sphinxcode{\sphinxupquote{/}} in a {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command.

\begin{sphinxadmonition}{note}{Example}

\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}

\sphinxAtStartPar
After that command the expression \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{f} \DUrole{name,builtin,pseudo}{\textbackslash{}}\DUrole{name}{o} \DUrole{name}{g}\DUrole{operator}{)}}} is left untouched by
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} while \sphinxcode{\sphinxupquote{\DUrole{operator}{((}\DUrole{name}{f} \DUrole{name,builtin,pseudo}{\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 {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} volatile, i.e.
always unfolded.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{volatile} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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 {} 
\sphinxAtStartPar
A {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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}

\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}

\sphinxAtStartPar
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 {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\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 {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{simpl nomatch}} indicates that a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} should not be unfolded if it would expose
a \sphinxcode{\sphinxupquote{match}} construct in the head position.  This affects the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}},
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}} tactics.

\begin{sphinxadmonition}{note}{Example}

\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}

\sphinxAtStartPar
In this case, \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.

\sphinxAtStartPar
In detail: the tactic {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} first applies βι\sphinxhyphen{}reduction. Then, it
expands transparent {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} and tries to reduce further using βι\sphinxhyphen{}reduction.
But, when no ι rule is applied after unfolding then
δ\sphinxhyphen{}reductions are not applied. For instance trying to use {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\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.

\end{itemize}


\subsubsection{Bidirectionality hints}
\label{\detokenize{language/extensions/arguments-command:bidirectionality-hints}}\label{\detokenize{language/extensions/arguments-command:id2}}
\sphinxAtStartPar
When type\sphinxhyphen{}checking an application, Coq normally does not use information from
the context to infer the types of the arguments. It only checks after the fact
that the type inferred for the application is coherent with the expected type.
Bidirectionality hints make it possible to specify that after type\sphinxhyphen{}checking the
first arguments of an application, typing information should be propagated from
the context to help inferring the types of the remaining arguments.

\sphinxAtStartPar
An {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command containing \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-arg_specs}]{\sphinxcrossref{\DUrole{hole}{arg\_specs$_{\text{1}}$}}}} \& {\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-arg_specs}]{\sphinxcrossref{\DUrole{hole}{arg\_specs$_{\text{2}}$}}}}}}}
provides bidirectionality hints.
It tells the typechecking algorithm, when type checking
applications of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, to first type check the arguments in
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-arg_specs}]{\sphinxcrossref{\DUrole{hole}{arg\_specs$_{\text{1}}$}}}}}}} and then propagate information from the typing context to
type check the remaining arguments (in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/extensions/arguments-command:grammar-token-arg_specs}]{\sphinxcrossref{\DUrole{hole}{arg\_specs$_{\text{2}}$}}}}}}}).

\begin{sphinxadmonition}{note}{Example: Bidirectionality hints}

\sphinxAtStartPar
In a context where a coercion was declared from \sphinxcode{\sphinxupquote{bool}} to \sphinxcode{\sphinxupquote{nat}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{b2n} \PYG{o}{(}\PYG{n}{b} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{if} \PYG{n}{b} \PYG{k}{then} \PYG{l+m+mi}{1} \PYG{k}{else} \PYG{l+m+mi}{0}\PYG{o}{.}
\PYG{k+kn}{Coercion} \PYG{n}{b2n} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Coq cannot automatically coerce existential statements over \sphinxcode{\sphinxupquote{bool}} to
statements over \sphinxcode{\sphinxupquote{nat}}, because the need for inserting a coercion is known
only from the expected type of a subterm:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{ex\PYGZus{}intro} \PYG{o}{\PYGZus{}} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{k}{exists} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\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}{ex\PYGZus{}intro ?P true ?y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{exists y, ?P y}\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}{exists n : nat, n \PYGZgt{} 0}\PYG{l+s+s2}{\PYGZdq{}}
    \PYG{o}{(}\PYG{n}{cannot} \PYG{n}{unify} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{bool}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{and} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{nat}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
However, a suitable bidirectionality hint makes the example work:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{ex\PYGZus{}intro} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZam{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{ex\PYGZus{}intro} \PYG{o}{\PYGZus{}} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{k}{exists} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{ex\PYGZus{}intro} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{n+nb+bp}{true} \PYG{o}{?}\PYG{n}{g} \PYG{o}{:} \PYG{k}{exists} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k}{exists} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{g} \PYG{o}{:} \PYG{o}{[} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{n+nb+bp}{true}\PYG{o}{]}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Coq will attempt to produce a term which uses the arguments you
provided, but in some cases involving Program mode the arguments after
the bidirectionality starts may be replaced by convertible but
syntactically different terms.


\subsection{Implicit Coercions}
\label{\detokenize{addendum/implicit-coercions:implicit-coercions}}\label{\detokenize{addendum/implicit-coercions:coercions}}\label{\detokenize{addendum/implicit-coercions::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
\sphinxAtStartPar
Amokrane Saïbi

\end{description}\end{quote}


\subsubsection{General Presentation}
\label{\detokenize{addendum/implicit-coercions:general-presentation}}
\sphinxAtStartPar
This section describes the inheritance mechanism of Coq. In 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 {} 
\sphinxAtStartPar
\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 {} 
\sphinxAtStartPar
\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 {} 
\sphinxAtStartPar
\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}


\subsubsection{Classes}
\label{\detokenize{addendum/implicit-coercions:classes}}
\sphinxAtStartPar
A class with \(n\) parameters is any defined name with a type
\sphinxcode{\sphinxupquote{\DUrole{notation}{forall ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{1}}$}}}})..({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{n}}$}}}}:{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{n}}$}}}}), {\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}}}.  Thus a class with
parameters is considered as a single class and not as a family of
classes.  An object of a class is any term of type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} .. {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{n}}$}}}}}}}.
In addition to these user\sphinxhyphen{}defined classes, we have two built\sphinxhyphen{}in classes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\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 {} 
\sphinxAtStartPar
\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}

\sphinxAtStartPar
Formally, the syntax of classes is defined as:
\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/implicit-coercions:grammar-token-class}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Funclass}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Sortclass}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}


\subsubsection{Coercions}
\label{\detokenize{addendum/implicit-coercions:id1}}
\sphinxAtStartPar
A name \sphinxcode{\sphinxupquote{f}} can be declared as a coercion between a source user\sphinxhyphen{}defined class
\sphinxcode{\sphinxupquote{C}} with \(n\) parameters and a target class \sphinxcode{\sphinxupquote{D}} if one of these
conditions holds:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{D}} is a user\sphinxhyphen{}defined class, then the type of \sphinxcode{\sphinxupquote{f}} must have the form
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x₁}\DUrole{operator}{:}\DUrole{name}{A₁}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Aₙ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{x₁}\DUrole{operator}{..}\DUrole{name}{xₙ}\DUrole{operator}{),} \DUrole{name}{D} \DUrole{name}{u₁}\DUrole{operator}{..}\DUrole{name}{uₘ}}} where \(m\)
is the number of parameters of \sphinxcode{\sphinxupquote{D}}.

\item {} 
\sphinxAtStartPar
\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₁}\DUrole{operator}{:}\DUrole{name}{A₁}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Aₙ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{x₁}\DUrole{operator}{..}\DUrole{name}{xₙ}\DUrole{operator}{)(}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{),} \DUrole{name}{B}}}.

\item {} 
\sphinxAtStartPar
\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₁}\DUrole{operator}{:}\DUrole{name}{A₁}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Aₙ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{x₁}\DUrole{operator}{..}\DUrole{name}{xₙ}\DUrole{operator}{),} \DUrole{name}{s}}} with \sphinxcode{\sphinxupquote{s}} a sort.

\end{itemize}

\sphinxAtStartPar
We then write \sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{operator}{:} \DUrole{name}{C} \DUrole{operator}{>\sphinxhyphen{}>} \DUrole{name}{D}}}. The restriction on the type
of coercions is called \sphinxstyleemphasis{the uniform inheritance condition}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The built\sphinxhyphen{}in class \sphinxcode{\sphinxupquote{Sortclass}} can be used as a source class, but
the built\sphinxhyphen{}in class \sphinxcode{\sphinxupquote{Funclass}} cannot.
\end{sphinxadmonition}

\sphinxAtStartPar
To coerce an object \sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{t₁}\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₁}\DUrole{operator}{..}\DUrole{name}{tₙ} \DUrole{name}{t}}} is
then an object of \sphinxcode{\sphinxupquote{D}}.


\subsubsection{Identity Coercions}
\label{\detokenize{addendum/implicit-coercions:identity-coercions}}
\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{n}} and \sphinxcode{\sphinxupquote{m}} parameters and
\sphinxcode{\sphinxupquote{\DUrole{name}{f}\DUrole{operator}{:}\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x₁}\DUrole{operator}{:}\DUrole{name}{T₁}\DUrole{operator}{)..(}\DUrole{name}{xₖ}\DUrole{operator}{:}\DUrole{name}{Tₖ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{u₁}\DUrole{operator}{..}\DUrole{name}{uₙ}\DUrole{operator}{),} \DUrole{name}{D} \DUrole{name}{v₁}\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}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{name}{C'} \DUrole{operator}{:=} \DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{x₁}\DUrole{operator}{:}\DUrole{name}{T₁}\DUrole{operator}{)..(}\DUrole{name}{xₖ}\DUrole{operator}{:}\DUrole{name}{Tₖ}\DUrole{operator}{)} \DUrole{operator}{=>} \DUrole{name}{C} \DUrole{name}{u₁}\DUrole{operator}{..}\DUrole{name}{uₙ}}}
\end{quote}

\sphinxAtStartPar
We then define an \sphinxstyleemphasis{identity coercion} between \sphinxcode{\sphinxupquote{C'}} and \sphinxcode{\sphinxupquote{C}}:
\begin{quote}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{name}{Id\_C'\_C}  \DUrole{operator}{:=} \DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{x₁}\DUrole{operator}{:}\DUrole{name}{T₁}\DUrole{operator}{)..(}\DUrole{name}{xₖ}\DUrole{operator}{:}\DUrole{name}{Tₖ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C'} \DUrole{name}{x₁}\DUrole{operator}{..}\DUrole{name}{xₖ}\DUrole{operator}{)} \DUrole{operator}{=>} \DUrole{operator}{(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{u₁}\DUrole{operator}{..}\DUrole{name}{uₙ}\DUrole{operator}{)}}}
\end{quote}

\sphinxAtStartPar
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₁}\DUrole{operator}{:}\DUrole{name}{T₁}\DUrole{operator}{)..(}\DUrole{name}{xₖ}\DUrole{operator}{:}\DUrole{name}{Tₖ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C'} \DUrole{name}{x₁}\DUrole{operator}{..}\DUrole{name}{xₖ}\DUrole{operator}{),}\DUrole{name}{D} \DUrole{name}{v₁}\DUrole{operator}{..}\DUrole{name}{vₘ}}}.

\sphinxAtStartPar
The identity coercions have a special status: to coerce an object
\sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{:}\DUrole{name}{C'} \DUrole{name}{t₁}\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₁}\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ⱼ}}.


\subsubsection{Inheritance Graph}
\label{\detokenize{addendum/implicit-coercions:inheritance-graph}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
We extend notations for coercions to coercion paths. For instance
\sphinxcode{\sphinxupquote{\DUrole{operator}{{[}}\DUrole{name}{f₁}\DUrole{operator}{;..;}\DUrole{name}{fₖ}\DUrole{operator}{{]}} \DUrole{operator}{:} \DUrole{name}{C} \DUrole{operator}{>\sphinxhyphen{}>} \DUrole{name}{D}}} is the coercion path composed
by the coercions \sphinxcode{\sphinxupquote{f₁..fₖ}}.  The application of a coercion path to a
term consists of the successive application of its coercions.


\subsubsection{Declaring Coercions}
\label{\detokenize{addendum/implicit-coercions:declaring-coercions}}\index{Coercion (command)@\spxentry{Coercion}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.Coercion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Coercion~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}~:~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}~>\sphinxhyphen{}>~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Coercion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_decl}]{\sphinxcrossref{\DUrole{hole}{univ\_decl}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/definitions:grammar-token-def_body}]{\sphinxcrossref{\DUrole{hole}{def\_body}}}}}}}}~\begin{quote}
\begin{quote}\begin{description}
\item[{name}] \leavevmode
\sphinxAtStartPar
Coercion; \_

\end{description}\end{quote}
\end{quote}

\sphinxAtStartPar
The first form declares the construction denoted by {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}} as a coercion between
the two given classes.  The second form defines {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
just like {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/universe-polymorphism:grammar-token-univ_decl}]{\sphinxcrossref{\DUrole{hole}{univ\_decl}}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/definitions:grammar-token-def_body}]{\sphinxcrossref{\DUrole{hole}{def\_body}}}}}}}
and then declares {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} as a coercion between it source and its target.
Both forms support the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which makes the coercion local to the current section.
\index{‘qualid’ not declared (error)@\spxentry{‘qualid’ not declared}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn._u2018qualid_u2019-not-declared}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~not~declared.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘qualid’ is already a coercion (error)@\spxentry{‘qualid’ is already a coercion}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn._u2018qualid_u2019-is-already-a-coercion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~already~a~coercion.}}}}
\end{fulllineitems}\end{savenotes}

\index{Funclass cannot be a source class (error)@\spxentry{Funclass cannot be a source class}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{‘qualid’ is not a function (error)@\spxentry{‘qualid’ is not a function}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn._u2018qualid_u2019-is-not-a-function}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~not~a~function.}}}}
\end{fulllineitems}\end{savenotes}

\index{Cannot find the source class of ‘qualid’ (error)@\spxentry{Cannot find the source class of ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.Cannot-find-the-source-class-of-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~the~source~class~of~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{Cannot recognize ‘class’ as a source class of ‘qualid’ (error)@\spxentry{Cannot recognize ‘class’ as a source class of ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.Cannot-recognize-_u2018class_u2019-as-a-source-class-of-_u2018qualid_u2019}}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘qualid’ does not respect the uniform inheritance condition (warning)@\spxentry{‘qualid’ does not respect the uniform inheritance condition}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:warn._u2018qualid_u2019-does-not-respect-the-uniform-inheritance-condition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~does~not~respect~the~uniform~inheritance~condition.}}}}
\end{fulllineitems}\end{savenotes}

\index{Found target class ... instead of ... (error)@\spxentry{Found target class ... instead of ...}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{New coercion path ... is ambiguous with existing ... (warning)@\spxentry{New coercion path ... is ambiguous with existing ...}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:warn.New-coercion-path-...-is-ambiguous-with-existing-...}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{New~coercion~path~...~is~ambiguous~with~existing~...}}}}
\sphinxAtStartPar
When the coercion {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is added to the inheritance graph, new
coercion paths which have the same classes as existing ones are ignored.
The {\hyperref[\detokenize{addendum/implicit-coercions:coq:cmd.Coercion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Coercion}}}}} command tries to check the convertibility of new ones and
existing ones. The paths for which this check fails are displayed by a warning
in the form \sphinxcode{\sphinxupquote{\DUrole{operator}{{[}}\DUrole{name}{f₁}\DUrole{operator}{;..;}\DUrole{name}{fₙ}\DUrole{operator}{{]}} \DUrole{operator}{:} \DUrole{name}{C} \DUrole{operator}{>\sphinxhyphen{}>} \DUrole{name}{D}}}.

\sphinxAtStartPar
The convertibility checking procedure for coercion paths is complete for
paths consisting of coercions satisfying the uniform inheritance condition,
but some coercion paths could be reported as ambiguous even if they are
convertible with existing ones when they have coercions that don't satisfy
the uniform inheritance condition.

\end{fulllineitems}\end{savenotes}

\index{... is not definitionally an identity function (warning)@\spxentry{... is not definitionally an identity function}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:warn....-is-not-definitionally-an-identity-function}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{...~is~not~definitionally~an~identity~function.}}}}
\sphinxAtStartPar
If a coercion path has the same source and target class, that is said to be
circular. When a new circular coercion path is not convertible with the
identity function, it will be reported as ambiguous.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Some objects can be declared as coercions when they are defined.
This applies to {\hyperref[\detokenize{language/core/assumptions:gallina-assumptions}]{\sphinxcrossref{\DUrole{std,std-ref}{assumptions}}}} and
constructors of {\hyperref[\detokenize{language/core/inductive:gallina-inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{inductive types and record fields}}}}.
Use \sphinxcode{\sphinxupquote{\DUrole{notation}{:>}}} instead of \sphinxcode{\sphinxupquote{\DUrole{notation}{:}}} before the
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} of the assumption to do so.  See \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-of_type}]{\sphinxcrossref{\DUrole{hole}{of\_type}}}}}}}.
\index{Identity Coercion (command)@\spxentry{Identity Coercion}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}~>\sphinxhyphen{}>~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{C}} is the source \sphinxcode{\sphinxupquote{class}} and \sphinxcode{\sphinxupquote{D}} the destination, we check
that \sphinxcode{\sphinxupquote{C}} is a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} with a {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} of the form
\sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{x₁}\DUrole{operator}{:}\DUrole{name}{T₁}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Tₙ}\DUrole{operator}{)} \DUrole{operator}{=>} \DUrole{name}{D} \DUrole{name}{t₁}\DUrole{operator}{..}\DUrole{name}{tₘ}}} where \sphinxcode{\sphinxupquote{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₁}\DUrole{operator}{:}\DUrole{name}{T₁}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Tₙ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{x₁}\DUrole{operator}{..}\DUrole{name}{xₙ}\DUrole{operator}{),}\DUrole{name}{D} \DUrole{name}{t₁}\DUrole{operator}{..}\DUrole{name}{tₘ}}},
and we declare it as an identity coercion between \sphinxcode{\sphinxupquote{C}} and \sphinxcode{\sphinxupquote{D}}.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which makes the coercion local to the current section.
\index{‘class’ must be a transparent constant (error)@\spxentry{‘class’ must be a transparent constant}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn._u2018class_u2019-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}\end{savenotes}

\index{SubClass (command)@\spxentry{SubClass}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.SubClass}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SubClass~{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~{\hyperref[\detokenize{language/core/definitions:grammar-token-def_body}]{\sphinxcrossref{\DUrole{hole}{def\_body}}}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} is a class \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\textquotesingle{}}}} applied to some arguments then
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is defined and an identity coercion of name
\sphinxcode{\sphinxupquote{\DUrole{notation}{Id\_{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\_{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\textquotesingle{}}}} is
declared. Otherwise said, this is an abbreviation for

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Definition {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}.}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{Identity Coercion Id\_{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\_{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\textquotesingle{} : {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} >\sphinxhyphen{}> {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\textquotesingle{}}}}.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which makes the coercion local to the current section.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\subsubsection{Displaying Available Coercions}
\label{\detokenize{addendum/implicit-coercions:displaying-available-coercions}}\index{Print Classes (command)@\spxentry{Print Classes}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.Print-Classes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Classes}}}}
\sphinxAtStartPar
Print the list of declared classes in the current context.

\end{fulllineitems}\end{savenotes}

\index{Print Coercions (command)@\spxentry{Print Coercions}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.Print-Coercions}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Coercions}}}}
\sphinxAtStartPar
Print the list of declared coercions in the current context.

\end{fulllineitems}\end{savenotes}

\index{Print Graph (command)@\spxentry{Print Graph}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.Print-Graph}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Graph}}}}
\sphinxAtStartPar
Print the list of valid coercion paths in the current context.

\end{fulllineitems}\end{savenotes}

\index{Print Coercion Paths (command)@\spxentry{Print Coercion Paths}\spxextra{command}}

\begin{savenotes}\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}}}}}}}}
\sphinxAtStartPar
Print the list of valid coercion paths between the two given classes.

\end{fulllineitems}\end{savenotes}



\subsubsection{Activating the Printing of Coercions}
\label{\detokenize{addendum/implicit-coercions:activating-the-printing-of-coercions}}\index{Printing Coercions (flag)@\spxentry{Printing Coercions}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:flag.Printing-Coercions}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Coercions}}}}
\sphinxAtStartPar
When on, this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} forces all the coercions to be printed.
By default, coercions are not printed.

\end{fulllineitems}\end{savenotes}

\index{Printing Coercion (table)@\spxentry{Printing Coercion}\spxextra{table}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-table}]{\sphinxtermref{\DUrole{xref,std,std-term}{table}}}} specifies a set of qualids for which coercions are always displayed.  Use the
{\hyperref[\detokenize{language/core/basic:coq:cmd.Add}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add}}}}} and {\hyperref[\detokenize{language/core/basic:coq:cmd.Remove}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove}}}}} commands to update the set of qualids.

\end{fulllineitems}\end{savenotes}



\subsubsection{Classes as Records}
\label{\detokenize{addendum/implicit-coercions:classes-as-records}}\label{\detokenize{addendum/implicit-coercions:coercions-classes-as-records}}
\index{:> (coercion)@\spxentry{:>}\spxextra{coercion}}\ignorespaces 
\sphinxAtStartPar
\sphinxstyleemphasis{Structures with Inheritance} may be defined using the {\hyperref[\detokenize{language/core/records:coq:cmd.Record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} command.

\sphinxAtStartPar
Use \sphinxcode{\sphinxupquote{>}} before the record name to declare the constructor name 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).  See {\hyperref[\detokenize{language/core/records:grammar-token-record_definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{record\_definition}}}}}.

\sphinxAtStartPar
Use \sphinxcode{\sphinxupquote{:>}} in the field type to declare the field as a coercion from the record name
to the class of the field type.  See {\hyperref[\detokenize{language/core/assumptions:grammar-token-of_type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{of\_type}}}}}.


\subsubsection{Coercions and Sections}
\label{\detokenize{addendum/implicit-coercions:coercions-and-sections}}
\sphinxAtStartPar
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.


\subsubsection{Coercions and Modules}
\label{\detokenize{addendum/implicit-coercions:coercions-and-modules}}
\sphinxAtStartPar
The coercions present in a module are activated only when the module is
explicitly imported.


\subsubsection{Examples}
\label{\detokenize{addendum/implicit-coercions:examples}}
\sphinxAtStartPar
There are three situations:


\paragraph{Coercion at function application}
\label{\detokenize{addendum/implicit-coercions:coercion-at-function-application}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{a}}} is ill\sphinxhyphen{}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}}.

\sphinxAtStartPar
We first give an example of coercion between atomic inductive types

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{bool\PYGZus{}in\PYGZus{}nat} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{n}{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{n}{bool} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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:}
\sphinxAtStartPar
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}

\sphinxAtStartPar
We give an example of coercion between classes with parameters.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameters} \PYG{o}{(}\PYG{n}{C} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{D} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{E} \PYG{o}{:} \PYG{n}{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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{n}{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{n}{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{n}{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{n}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
We give now an example using identity coercions.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{D\PYGZsq{}} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{n}{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{n}{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{n}{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{n}{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{k+kn}{Arguments} \PYG{n}{IdD\PYGZsq{}D} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{bool\PYGZus{}scope} \PYG{o}{\PYGZus{}}
    \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{n}{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{n}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
In the case of functional arguments, we use the monotonic rule of
sub\sphinxhyphen{}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:

\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{n}{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{n}{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{n}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Remark the changes in the result following the modification of the
previous example.

\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{n}{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{n}{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{n}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}


\paragraph{Coercion to a type}
\label{\detokenize{addendum/implicit-coercions:coercion-to-a-type}}
\sphinxAtStartPar
An assumption \sphinxcode{\sphinxupquote{x:A}} when \sphinxcode{\sphinxupquote{A}} is not a type, is ill\sphinxhyphen{}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}{=>} \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\sphinxhyphen{})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.

\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}


\paragraph{Coercion to a function}
\label{\detokenize{addendum/implicit-coercions:coercion-to-a-function}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{f a}} is ill\sphinxhyphen{}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.

\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{n}{nat} \PYG{n}{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{n}{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{n}{nat} \PYG{n}{nat} \PYG{n}{b} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{n}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Let us see the resulting graph after all these examples.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{k+kn}{Graph}\PYG{o}{.}
    \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}{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}{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}
    \PYG{o}{[}\PYG{n}{bool\PYGZus{}in\PYGZus{}nat}\PYG{o}{]} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
\end{sphinxVerbatim}


\subsection{Typeclasses}
\label{\detokenize{addendum/type-classes:typeclasses}}\label{\detokenize{addendum/type-classes:id1}}\label{\detokenize{addendum/type-classes::doc}}
\sphinxAtStartPar
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 {[}\hyperlink{cite.zebibliography:id49}{SO08}{]} and the literature on type
classes in Haskell which also applies.


\subsubsection{Class and Instance declarations}
\label{\detokenize{addendum/type-classes:class-and-instance-declarations}}
\sphinxAtStartPar
The syntax for class and instance declarations is the same as the record
syntax of Coq:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Class} \PYG{n}{classname} \PYG{o}{(}\PYG{n}{p1} \PYG{o}{:} \PYG{n}{t1}\PYG{o}{)} \PYG{n+nb+bp}{⋯} \PYG{o}{(}\PYG{n}{pn} \PYG{o}{:} \PYG{n}{tn}\PYG{o}{)} \PYG{o}{[}\PYG{o}{:} \PYG{n}{sort}\PYG{o}{]} \PYG{o}{:=} \PYG{o}{\PYGZob{}} \PYG{n}{f1} \PYG{o}{:} \PYG{n}{u1} \PYG{o}{;} \PYG{n+nb+bp}{⋯} \PYG{o}{;} \PYG{n}{fm} \PYG{o}{:} \PYG{n}{um} \PYG{o}{\PYGZcb{}}\PYG{o}{.}

\PYG{k+kn}{Instance} \PYG{n}{instancename} \PYG{n}{q1} \PYG{n+nb+bp}{⋯} \PYG{n}{qm} \PYG{o}{:} \PYG{n}{classname} \PYG{n}{p1} \PYG{n+nb+bp}{⋯} \PYG{n}{pn} \PYG{o}{:=} \PYG{o}{\PYGZob{}} \PYG{n}{f1} \PYG{o}{:=} \PYG{n}{t1} \PYG{o}{;} \PYG{n+nb+bp}{⋯} \PYG{o}{;} \PYG{n}{fm} \PYG{o}{:=} \PYG{n}{tm} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{pi : ti}} variables are called the \sphinxstyleemphasis{parameters} of the class and
the \sphinxcode{\sphinxupquote{fi : ti}} 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 \sphinxcode{\sphinxupquote{instancename}} and type is an
instantiation of the record type.

\sphinxAtStartPar
We’ll use the following example class in the rest of the chapter:

\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{n}{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}

\sphinxAtStartPar
This class implements a boolean equality test which is compatible with
Leibniz equality on some type. An example implementation is:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Instance} \PYG{n}{unit\PYGZus{}EqDec} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{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{o}{|} \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}

\sphinxAtStartPar
Using the {\hyperref[\detokenize{addendum/type-classes:coq:attr.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} attribute, if the term is not sufficient to
finish the definition (e.g. due to a missing field or non\sphinxhyphen{}inferable
hole) it must be finished in proof mode. If it is sufficient a trivial
proof mode with no open goals is started.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{\PYGZsh{}}\PYG{o}{[}\PYG{k}{refine}\PYG{o}{]} \PYG{k+kn}{Instance} \PYG{n}{unit\PYGZus{}EqDec\PYGZsq{}} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{unit} \PYG{o}{:=} \PYG{o}{\PYGZob{}} \PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k}{intros} \PYG{n+nb+bp}{[]} \PYG{n+nb+bp}{[]}\PYG{o}{;}\PYG{k+kp}{reflexivity}\PYG{o}{.} \PYG{k+kn}{Defined}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that if you finish the proof with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} the entire instance
will be opaque, including the fields given in the initial term.

\sphinxAtStartPar
Alternatively, in {\hyperref[\detokenize{addendum/program:coq:flag.Program-Mode}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Program Mode}}}}} if one does not give all the
members in the Instance declaration, Coq generates obligations for the
remaining fields, e.g.:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Program}\PYG{o}{.}\PYG{n}{Tactics}\PYG{o}{.}
\PYG{n}{Program} \PYG{k+kn}{Instance} \PYG{n}{eq\PYGZus{}bool} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Next} \PYG{n}{Obligation}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}

  \PYG{k}{destruct} \PYG{n}{x} \PYG{o}{;} \PYG{k}{destruct} \PYG{n}{y} \PYG{o}{;} \PYG{o}{(}\PYG{k+kp}{discriminate} \PYG{o}{|}\PYG{o}{|} \PYG{k+kp}{reflexivity}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{k+kn}{Defined}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute to get richer
facilities for dealing with obligations.


\subsubsection{Binding classes}
\label{\detokenize{addendum/type-classes:binding-classes}}
\sphinxAtStartPar
Once a typeclass is declared, one can use it in class binders:

\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}

\sphinxAtStartPar
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:

\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}{The} \PYG{n}{following} \PYG{n}{term} \PYG{n}{contains} \PYG{n}{unresolved} \PYG{n}{implicit} \PYG{n}{arguments}\PYG{o}{:}
      \PYG{o}{(}\PYG{k}{fun} \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}{=\PYGZgt{}} \PYG{n}{negb} \PYG{o}{(}\PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{)}
    \PYG{n}{More} \PYG{n}{precisely}\PYG{o}{:} 
    \PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{EqDec}\PYG{o}{:} \PYG{n}{Cannot} \PYG{n}{infer} \PYG{n}{the} \PYG{n}{implicit} \PYG{n}{parameter} \PYG{n}{EqDec} \PYG{k}{of} \PYG{n}{eqb} \PYG{n}{whose} \PYG{n}{type} \PYG{k}{is}
      \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{EqDec A}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{(}\PYG{n}{no} \PYG{n}{type} \PYG{n}{class} \PYG{n}{instance} \PYG{n}{found}\PYG{o}{)} \PYG{k}{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}
\end{sphinxVerbatim}

\sphinxAtStartPar
The algorithm used to solve constraints is a variant of the {\hyperref[\detokenize{proofs/automatic-tactics/auto: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:

\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}

\sphinxAtStartPar
However, the generalizing binders should be used instead as they have
particular support for typeclasses:
\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
They support implicit quantification on partially applied type
classes ({\hyperref[\detokenize{language/extensions/implicit-arguments:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit generalization}}}}). Any argument not given as part of a typeclass
binder will be automatically generalized.

\item {} 
\sphinxAtStartPar
They also support implicit quantification on {\hyperref[\detokenize{addendum/type-classes:superclasses}]{\sphinxcrossref{\DUrole{std,std-ref}{Superclasses}}}}.

\end{itemize}

\sphinxAtStartPar
Following the previous example, one can write:

\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}

\sphinxAtStartPar
Here \sphinxcode{\sphinxupquote{A}} is implicitly generalized, and the resulting function is
equivalent to the one above.


\subsubsection{Parameterized Instances}
\label{\detokenize{addendum/type-classes:parameterized-instances}}
\sphinxAtStartPar
One can declare parameterized instances as in Haskell simply by giving
the constraints as a binding context before the instance, e.g.:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Program} \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}{|} \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}

\sphinxAtStartPar
These instances are used just as well as lemmas in the instance hint
database.


\subsubsection{Sections and contexts}
\label{\detokenize{addendum/type-classes:sections-and-contexts}}\label{\detokenize{addendum/type-classes:contexts}}
\sphinxAtStartPar
To ease developments parameterized by many instances, one can use the
{\hyperref[\detokenize{language/core/sections:coq:cmd.Context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Context}}}}} command to introduce the parameters into the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-local-context}]{\sphinxtermref{\DUrole{xref,std,std-term}{local context}}}},
it works similarly to the command {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}}, except it accepts any
binding context as an argument, so variables can be implicit, and
{\hyperref[\detokenize{language/extensions/implicit-arguments:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit generalization}}}} can be used.
For example:

\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}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{\PYGZsh{}}\PYG{o}{[} \PYG{n}{global}\PYG{o}{,} \PYG{n}{program} \PYG{o}{]} \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}{|} \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}{|} \PYG{n}{None}\PYG{o}{,} \PYG{n}{None} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
         \PYG{o}{|} \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{n}{Admit} \PYG{n}{Obligations}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}}\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{n}{option\PYGZus{}eqb} \PYG{k}{is} \PYG{n}{not} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{k+kn}{Arguments} \PYG{n}{option\PYGZus{}eqb} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZob{}}\PYG{n}{EA}\PYG{o}{\PYGZcb{}}
    \PYG{n}{option\PYGZus{}eqb} \PYG{k}{is} \PYG{n}{transparent}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{option\PYGZus{}eqb}
\end{sphinxVerbatim}

\sphinxAtStartPar
Here the {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attribute redeclares the instance at the end of the
section, once it has been generalized by the context variables it
uses.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
Section {\hyperref[\detokenize{language/core/sections:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}




\subsubsection{Building hierarchies}
\label{\detokenize{addendum/type-classes:building-hierarchies}}

\paragraph{Superclasses}
\label{\detokenize{addendum/type-classes:superclasses}}\label{\detokenize{addendum/type-classes:id3}}
\sphinxAtStartPar
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:

\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{n}{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}

\sphinxAtStartPar
Contrary to Haskell, we have no special syntax for superclasses, but
this declaration is equivalent to:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Class} \PYG{o}{`}\PYG{o}{(}\PYG{n}{E} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{Ord} \PYG{n}{A} \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{n}{bool} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\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}

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{!}} modifier switches the way a binder is parsed back to the usual
interpretation of Coq. In particular, it uses the implicit arguments
mechanism if available, as shown in the example.


\paragraph{Substructures}
\label{\detokenize{addendum/type-classes:substructures}}
\index{:> (substructure)@\spxentry{:>}\spxextra{substructure}}\ignorespaces 
\sphinxAtStartPar
Substructures are components of a class which are instances of a class
themselves. They often arise when using classes for logical
properties, e.g.:

\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}

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
The syntax \sphinxcode{\sphinxupquote{:>}} 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.
\index{Ignored instance declaration for “‘ident’”: “‘term’” is not a class (warning)@\spxentry{Ignored instance declaration for “‘ident’”: “‘term’” is not a class}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:warn.Ignored-instance-declaration-for-_u201c_u2018ident_u2019_u201d:-_u201c_u2018term_u2019_u201d-is-not-a-class}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ignored~instance~declaration~for~“{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}”:~“{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}”~is~not~a~class}}}}
\sphinxAtStartPar
Using this \sphinxcode{\sphinxupquote{:>}} syntax with a right\sphinxhyphen{}hand\sphinxhyphen{}side that is not itself a Class
has no effect (apart from emitting this warning). In particular, is does not
declare a coercion.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
One can also declare existing objects or structure projections using
the Existing Instance command to achieve the same effect.


\subsubsection{Summary of the commands}
\label{\detokenize{addendum/type-classes:summary-of-the-commands}}\index{Class (command)@\spxentry{Class}\spxextra{command}}

\begin{savenotes}\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/core/records:grammar-token-record_definition}]{\sphinxcrossref{\DUrole{hole}{record\_definition}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Class~{\hyperref[\detokenize{addendum/type-classes:grammar-token-singleton_class_definition}]{\sphinxcrossref{\DUrole{hole}{singleton\_class\_definition}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/type-classes:grammar-token-singleton_class_definition}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/type-classes:grammar-token-singleton_class_definition}]{\sphinxcrossref{\DUrole{hole}{singleton\_class\_definition}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{>}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/inductive:grammar-token-constructor}]{\sphinxcrossref{\DUrole{hole}{constructor}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The first form declares a record and makes the record a typeclass with parameters
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}}}} and the listed record fields.

\phantomsection\label{\detokenize{addendum/type-classes:singleton-class}}
\sphinxAtStartPar
The second form declares a \sphinxstyleemphasis{singleton} class with a single method.  This
singleton class is a so\sphinxhyphen{}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 {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} itself is
declared rigid during resolution so that the class abstraction is
maintained.

\sphinxAtStartPar
Like any command declaring a record, this command supports the
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}}, {\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template)}}}}},
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative)}}}}}, and {\hyperref[\detokenize{language/core/variants:coq:attr.private(matching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{private(matching)}}}}}
attributes.
\index{Existing Class (command)@\spxentry{Existing Class}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
This variant declares a class from a previously declared {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} or
inductive definition. No methods or instances are defined.
\index{‘ident’ is already declared as a typeclass (warning)@\spxentry{‘ident’ is already declared as a typeclass}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:warn._u2018ident_u2019-is-already-declared-as-a-typeclass}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~declared~as~a~typeclass}}}}
\sphinxAtStartPar
This command has no effect when used on a typeclass.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Instance (command)@\spxentry{Instance}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.Instance}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Instance~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hint_info}]{\sphinxcrossref{\DUrole{hole}{hint\_info}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{:=~\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/records:grammar-token-field_def}]{\sphinxcrossref{\DUrole{hole}{field\_def}}}}}\DUrole{notation-sup}{*}}~\}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Declares a typeclass instance named
{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident\_decl}}}}} of the class \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} with the specified parameters and with
fields defined by {\hyperref[\detokenize{language/core/records:grammar-token-field_def}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{field\_def}}}}}, where each field must be a declared field of
the class.

\sphinxAtStartPar
Adds one or more {\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}}s to declare a parameterized instance. {\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hint_info}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hint\_info}}}}}
may be used to specify the hint priority, where 0 is the highest priority as for
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} hints. If the priority is not specified, the default is the number
of non\sphinxhyphen{}dependent binders of the instance.  If {\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_pattern}}}}} is given, terms
matching that pattern will trigger use of the instance.  Otherwise,
use is triggered based on the conclusion of the type.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}}, {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} and {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}}
locality attributes.

\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.14: }The default value for instance locality will change in a future
release. Instances added outside of sections without an explicit
locality are now deprecated. We recommend using {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}}
where possible.

\sphinxAtStartPar
Like {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}, it also supports the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}}
attribute to switch the type checking to \sphinxcode{\sphinxupquote{Program}} (chapter
{\hyperref[\detokenize{addendum/program:programs}]{\sphinxcrossref{\DUrole{std,std-ref}{Program}}}}) and to use the obligation mechanism to manage missing
fields.

\sphinxAtStartPar
Finally, it supports the lighter {\hyperref[\detokenize{addendum/type-classes:coq:attr.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} attribute:
\index{refine (attribute)@\spxentry{refine}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:attr.refine}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{refine}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}} can be used to leave holes or not provide all
fields in the definition of an instance and open the tactic mode
to fill them.  It works exactly as if no {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} had been given and
the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic has been used first.

\end{fulllineitems}\end{savenotes}

\index{Declare Instance (command)@\spxentry{Declare Instance}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.Declare-Instance}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Instance~{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hint_info}]{\sphinxcrossref{\DUrole{hole}{hint\_info}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
In a {\hyperref[\detokenize{language/core/modules:coq:cmd.Module-Type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module Type}}}}}, declares that a corresponding concrete
instance should exist in any implementation of this {\hyperref[\detokenize{language/core/modules:coq:cmd.Module-Type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module Type}}}}}. This
is similar to the distinction between {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Parameter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Parameter}}}}} vs. {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}, or
between {\hyperref[\detokenize{language/core/modules:coq:cmd.Declare-Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare Module}}}}} and {\hyperref[\detokenize{language/core/modules:coq:cmd.Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Existing Instance (command)@\spxentry{Existing Instance}\spxextra{command}}\index{Existing Instances (command)@\spxentry{Existing Instances}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.Existing-Instance}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Existing~Instance~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hint_info}]{\sphinxcrossref{\DUrole{hole}{hint\_info}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.Existing-Instances}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Existing~Instances~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{|~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Adds a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} whose type ends with
an applied typeclass to the instance database with an optional
priority {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}.  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/type-classes:coq:cmd.Print-Instances}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Instances}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Instance Generalized Output (flag)@\spxentry{Instance Generalized Output}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.Instance-Generalized-Output}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Instance~Generalized~Output}}}}~
\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.13.}

\sphinxAtStartPar
Disabled by default, this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} provides compatibility with Coq
version 8.12 and earlier.

\sphinxAtStartPar
When enabled, the type of the instance is implicitly generalized
over unbound and {\hyperref[\detokenize{language/extensions/implicit-arguments:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{generalizable}}}} variables as though surrounded by \sphinxcode{\sphinxupquote{\textbackslash{}`\{\}}}.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Print Instances (command)@\spxentry{Print Instances}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.Print-Instances}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Instances~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}
\sphinxAtStartPar
Shows the list of instances associated with the typeclass {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}}.

\end{fulllineitems}\end{savenotes}

\index{typeclasses eauto (tactic)@\spxentry{typeclasses eauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{typeclasses~eauto~\DUrole{repeat-wrapper}{\DUrole{repeat}{bfs}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This proof search tactic uses the resolution engine that is run
implicitly during type checking. This tactic uses a different resolution
engine than {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} and {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}. The main differences are the
following:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Unlike {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} and {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}, the resolution is done entirely in
the proof engine, meaning that backtracking is
available among dependent subgoals, and shelving goals is supported.
\sphinxcode{\sphinxupquote{typeclasses eauto}} is a multi\sphinxhyphen{}goal tactic. It analyses the dependencies
between subgoals to avoid backtracking on subgoals that are entirely
independent.

\item {} 
\sphinxAtStartPar
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{proofs/automatic-tactics/auto:coq:cmd.Create-HintDb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Create HintDb}}}}} for example) with unfoldable variables and
{\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} as the first argument of \sphinxcode{\sphinxupquote{typeclasses eauto}} hence makes
resolution with the local hypotheses use full conversion during
unification.

\item {} 
\sphinxAtStartPar
The mode hints (see {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Mode}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Mode}}}}}) associated with a class are
taken into account by {\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}}. When a goal
does not match any of the declared modes for its head (if any),
instead of failing like {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}}, the goal is suspended and
resolution proceeds on the remaining goals.
If after one run of resolution, there remains suspended goals,
resolution is launched against on them, until it reaches a fixed
point when the set of remaining suspended goals does not change.
Using \sphinxcode{\sphinxupquote{solve {[}typeclasses eauto{]}}} can be used to ensure that
no suspended goals remain.

\item {} 
\sphinxAtStartPar
When considering local hypotheses, we use the union of all the modes
declared in the given databases.

\item {} 
\sphinxAtStartPar
Use the {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses eauto}}}}} command to customize the behavior of
this tactic.

\end{itemize}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}}}}] \leavevmode
\sphinxAtStartPar
Specifies the maximum depth of the search.
\begin{quote}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The semantics for the limit \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}}}
are different than for {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}. By default, if no limit is given, the
search is unbounded. Unlike {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}, introduction steps count against
the limit, which might result in larger limits being necessary when
searching with {\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}} than with {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}.
\end{sphinxadmonition}
\end{quote}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{with \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}] \leavevmode
\sphinxAtStartPar
Runs resolution with the specified hint databases. It treats
typeclass subgoals the same as other subgoals (no shelving of
non\sphinxhyphen{}typeclass goals in particular), while allowing shelved goals
to remain at any point during search.

\sphinxAtStartPar
When \sphinxcode{\sphinxupquote{\DUrole{notation}{with}}} is not specified, {\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}} uses
the \sphinxcode{\sphinxupquote{typeclass\_instances}} database by default (instead of \sphinxcode{\sphinxupquote{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:}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{all:once (typeclasses eauto)}} faithfully
mimics 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\sphinxhyphen{}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}

\end{description}

\end{fulllineitems}\end{savenotes}

\index{autoapply (tactic)@\spxentry{autoapply}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:tacn.autoapply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autoapply~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
The tactic \sphinxcode{\sphinxupquote{autoapply}} applies {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}} using the transparency information
of the hint database {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, and does \sphinxstyleemphasis{no} typeclass resolution. This can
be used in {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.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}\end{savenotes}



\paragraph{Typeclasses Transparent, Typeclasses Opaque}
\label{\detokenize{addendum/type-classes:typeclasses-transparent-typeclasses-opaque}}\label{\detokenize{addendum/type-classes:typeclassestransparent}}\index{Typeclasses Transparent (command)@\spxentry{Typeclasses Transparent}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Makes {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} transparent during typeclass
resolution.
A shortcut for {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Transparent}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} : typeclass\_instances}}}

\end{fulllineitems}\end{savenotes}

\index{Typeclasses Opaque (command)@\spxentry{Typeclasses Opaque}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Make {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} opaque for typeclass search.
A shortcut for {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Opaque}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} : typeclass\_instances}}}.

\sphinxAtStartPar
It is useful when some {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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{proofs/automatic-tactics/auto:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The hints databases for auto and eauto}}}}).

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
By default, all {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{relation} \PYG{n}{A} \PYG{o}{:=} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
\end{sphinxVerbatim}


\paragraph{Settings}
\label{\detokenize{addendum/type-classes:settings}}\index{Typeclasses Dependency Order (flag)@\spxentry{Typeclasses Dependency Order}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (off by default) respects the dependency order
between subgoals, meaning that subgoals on which other subgoals depend
come first, while the non\sphinxhyphen{}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}\end{savenotes}

\index{Typeclasses Filtered Unification (flag)@\spxentry{Typeclasses Filtered Unification}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}, which is off by default, switches the
hint application procedure to a filter\sphinxhyphen{}then\sphinxhyphen{}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 {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} to
explicitly appear in the pattern will make it never apply on a goal
where there is a hole in that place.

\end{fulllineitems}\end{savenotes}

\index{Typeclasses Limit Intros (flag)@\spxentry{Typeclasses Limit Intros}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (on by default) controls the ability to apply hints while
avoiding (functional) eta\sphinxhyphen{}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:}
\sphinxAtStartPar
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}\end{savenotes}

\index{Typeclass Resolution For Conversion (flag)@\spxentry{Typeclass Resolution For Conversion}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (on by default) controls the use of typeclass resolution
when a unification problem cannot be solved during elaboration/type
inference. With this flag on, when a unification fails, typeclass
resolution is tried before launching unification once again.

\end{fulllineitems}\end{savenotes}

\index{Typeclasses Strict Resolution (flag)@\spxentry{Typeclasses Strict Resolution}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Typeclass declarations introduced when this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is set have a
stricter resolution behavior (the flag 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}\end{savenotes}

\index{Typeclasses Unique Solutions (flag)@\spxentry{Typeclasses Unique Solutions}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
When a typeclass resolution is launched we ensure that it has a single
solution or fail. This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} ensures that the resolution is canonical, but
can make proof search much more expensive.

\end{fulllineitems}\end{savenotes}

\index{Typeclasses Unique Instances (flag)@\spxentry{Typeclasses Unique Instances}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Typeclass declarations introduced when this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is set have a more
efficient resolution behavior (the flag 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}\end{savenotes}

\index{Typeclasses Iterative Deepening (flag)@\spxentry{Typeclasses Iterative Deepening}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.Typeclasses-Iterative-Deepening}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Iterative~Deepening}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is set, the proof search strategy is breadth\sphinxhyphen{}first search.
Otherwise, the search strategy is depth\sphinxhyphen{}first search.  The default is off.
{\hyperref[\detokenize{addendum/type-classes:coq:cmd.Typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses eauto}}}}} is another way to set this flag.

\end{fulllineitems}\end{savenotes}

\index{Typeclasses Depth (option)@\spxentry{Typeclasses Depth}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:opt.Typeclasses-Depth}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Depth~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} sets the maximum proof search depth.  The default is unbounded.
{\hyperref[\detokenize{addendum/type-classes:coq:cmd.Typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses eauto}}}}} is another way to set this option.

\end{fulllineitems}\end{savenotes}

\index{Typeclasses Debug (flag)@\spxentry{Typeclasses Debug}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.Typeclasses-Debug}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Debug}}}}
\sphinxAtStartPar
Controls whether typeclass resolution steps are shown during search.  Setting this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}
also sets {\hyperref[\detokenize{addendum/type-classes:coq:opt.Typeclasses-Debug-Verbosity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses Debug Verbosity}}}}} to 1.  {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses eauto}}}}}
is another way to set this flag.

\end{fulllineitems}\end{savenotes}

\index{Typeclasses Debug Verbosity (option)@\spxentry{Typeclasses Debug Verbosity}\spxextra{option}}

\begin{savenotes}\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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
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 {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} to 1 or 2 turns on the {\hyperref[\detokenize{addendum/type-classes:coq:flag.Typeclasses-Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses Debug}}}}} flag; setting this
option to 0 turns that flag off.

\end{fulllineitems}\end{savenotes}



\paragraph{Typeclasses eauto}
\label{\detokenize{addendum/type-classes:typeclasses-eauto}}\index{Typeclasses eauto (command)@\spxentry{Typeclasses eauto}\spxextra{command}}

\begin{savenotes}\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{alternative}{\DUrole{alternative-block}{bfs}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{dfs}}~)}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Allows more global customization of the {\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}} tactic.
The options are:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{debug}}}] \leavevmode
\sphinxAtStartPar
Sets debug mode. In debug mode, a trace of
successfully applied tactics is printed. Debug mode can also
be set with {\hyperref[\detokenize{addendum/type-classes:coq:flag.Typeclasses-Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses Debug}}}}}.

\item[{\sphinxcode{\sphinxupquote{dfs}}, \sphinxcode{\sphinxupquote{bfs}}}] \leavevmode
\sphinxAtStartPar
Sets the search strategy to depth\sphinxhyphen{}first
search (the default) or breadth\sphinxhyphen{}first search. The search strategy
can also be set with {\hyperref[\detokenize{addendum/type-classes:coq:flag.Typeclasses-Iterative-Deepening}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses Iterative Deepening}}}}}.

\item[{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}}] \leavevmode
\sphinxAtStartPar
Sets the depth limit for the search. The limit can also be set with
{\hyperref[\detokenize{addendum/type-classes:coq:opt.Typeclasses-Depth}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses Depth}}}}}.

\end{description}

\end{fulllineitems}\end{savenotes}



\subsection{Canonical Structures}
\label{\detokenize{language/extensions/canonical:canonical-structures}}\label{\detokenize{language/extensions/canonical:canonicalstructures}}\label{\detokenize{language/extensions/canonical::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
\sphinxAtStartPar
Assia Mahboubi and Enrico Tassi

\end{description}\end{quote}

\sphinxAtStartPar
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 {[}\hyperlink{cite.zebibliography:id17}{MT13}{]}. 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 {[}\hyperlink{cite.zebibliography:id16}{GZND11}{]} 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.
\begin{quote}
\end{quote}


\subsubsection{Declaration of canonical structures}
\label{\detokenize{language/extensions/canonical:declaration-of-canonical-structures}}\label{\detokenize{language/extensions/canonical:canonical-structure-declaration}}
\sphinxAtStartPar
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{language/extensions/canonical:canonicalstructures}]{\sphinxcrossref{\DUrole{std,std-ref}{Canonical Structures}}}}; here only a simple example is given.
\index{Canonical Structure (command)@\spxentry{Canonical Structure}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/canonical:coq:cmd.Canonical-Structure}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Canonical~\DUrole{repeat-wrapper}{\DUrole{repeat}{Structure}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}\phantomsection\label{\detokenize{language/extensions/canonical:id3}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Canonical~\DUrole{repeat-wrapper}{\DUrole{repeat}{Structure}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~{\hyperref[\detokenize{language/core/definitions:grammar-token-def_body}]{\sphinxcrossref{\DUrole{hole}{def\_body}}}}}}}}
\sphinxAtStartPar
The first form of this command declares an existing \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} as a
canonical instance of a structure (a record).

\sphinxAtStartPar
The second form defines a new {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} as if the {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} command
had been used, then declares it as a canonical instance as if the first
form had been used on the defined object.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute.  When used, the
structure is canonical only within the {\hyperref[\detokenize{language/core/sections:coq:cmd.Section}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Section}}}}} containing it.

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} (in {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}}) denotes an object \sphinxcode{\sphinxupquote{\DUrole{notation}{(Build\_struct c$_{\text{1}}$ … c$_{\text{n}}$)}}} in the
structure \sphinxcode{\sphinxupquote{\DUrole{keyword}{struct}}} for which the fields are \sphinxcode{\sphinxupquote{\DUrole{notation}{x$_{\text{1}}$, …, x$_{\text{n}}$}}}.
Then, each time an equation of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{(x$_{\text{i}}$ \_)}}} \sphinxcode{\sphinxupquote{=}}\(_{βδιζ}\) \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}} has to be
solved during the type checking process, {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is used as a solution.
Otherwise said, {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is canonically used to extend the field \sphinxcode{\sphinxupquote{\DUrole{notation}{x$_{\text{i}}$}}}
into a complete structure built on \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}} when \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}} unifies with \sphinxcode{\sphinxupquote{\DUrole{notation}{(x$_{\text{i}}$ \_)}}}.

\sphinxAtStartPar
The following kinds of terms are supported for the fields \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}} of {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{Constants}}}} and section variables of an active section,
applied to zero or more arguments.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/sorts:grammar-token-sort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort}}}}}s.

\item {} 
\sphinxAtStartPar
Literal functions:  \sphinxcode{\sphinxupquote{fun … => …}}.

\item {} 
\sphinxAtStartPar
Literal, (possibly dependent) function types: \sphinxcode{\sphinxupquote{… \sphinxhyphen{}> …}} and \sphinxcode{\sphinxupquote{forall …, …}}.

\item {} 
\sphinxAtStartPar
Variables bound in {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}.

\end{itemize}

\sphinxAtStartPar
Only the head symbol of an existing instance's field \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}}
is considered when searching for a canonical extension.
We call this head symbol the \sphinxstyleemphasis{key} and we say "{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} \sphinxstyleemphasis{keys} the field \sphinxcode{\sphinxupquote{\DUrole{notation}{x$_{\text{i}}$}}} to \sphinxcode{\sphinxupquote{\DUrole{notation}{k}}}" when \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}}'s
head symbol is \sphinxcode{\sphinxupquote{\DUrole{notation}{k}}}.
Keys are the only piece of information that is used for canonical extension.
The keys corresponding to the kinds of terms listed above are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
For constants and section variables, potentially applied to arguments:
the constant or variable itself, disregarding any arguments.

\item {} 
\sphinxAtStartPar
For sorts: the sort itself.

\item {} 
\sphinxAtStartPar
For literal functions: skip the abstractions and use the key of the body.

\item {} 
\sphinxAtStartPar
For literal function types: a disembodied implication key denoted \sphinxcode{\sphinxupquote{forall \_, \_}}, disregarding both its
domain and codomain.

\item {} 
\sphinxAtStartPar
For variables bound in {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}: a catch\sphinxhyphen{}all key denoted \sphinxcode{\sphinxupquote{\_}}.

\end{itemize}

\sphinxAtStartPar
This means that, for example, \sphinxcode{\sphinxupquote{(some\_constant x1)}} and \sphinxcode{\sphinxupquote{(some\_constant (other\_constant y1 y2) x2)}}
are not distinct keys.

\sphinxAtStartPar
Variables bound in {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} match any term for the purpose of canonical extension.
This has two major consequences for a field \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}} keyed to a variable of {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
Unless another key—and, thus, instance—matches \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}}, the instance will always be considered by
unification.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}} will be considered overlapping not distinct from any other canonical instance
that keys \sphinxcode{\sphinxupquote{\DUrole{notation}{x$_{\text{i}}$}}} to one of its own variables.

\end{enumerate}

\sphinxAtStartPar
A record field \sphinxcode{\sphinxupquote{\DUrole{notation}{x$_{\text{i}}$}}} can only be keyed once to each key.
Coq prints a warning when {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} keys \sphinxcode{\sphinxupquote{\DUrole{notation}{x$_{\text{i}}$}}} to a term
whose head symbol is already keyed by an existing canonical instance.
In this case, Coq will not register that {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} as a canonical
extension.
(The remaining fields of the instance can still be used for canonical extension.)

\sphinxAtStartPar
Canonical structures are particularly useful when mixed with coercions
and strict implicit arguments.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Here is an example.

\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{n}{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{n}{nat\PYGZus{}setoid}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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:}
\sphinxAtStartPar
If a same field occurs in several canonical structures, then
only the structure declared first as canonical is considered.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{canonical (attribute)@\spxentry{canonical}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/canonical:coq:attr.canonical}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{canonical\DUrole{repeat-wrapper}{\DUrole{repeat}{=~\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{boolean attribute}}}} can decorate a {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} or
{\hyperref[\detokenize{language/core/sections:coq:cmd.Let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let}}}}} command.  It is equivalent to having a {\hyperref[\detokenize{language/extensions/canonical:coq:cmd.Canonical-Structure}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Canonical
Structure}}}}} declaration just after the command.

\sphinxAtStartPar
To prevent a field from being involved in the inference of
canonical instances, its declaration can be annotated with
\sphinxcode{\sphinxupquote{canonical=no}} (cf. the syntax of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/records:grammar-token-record_field}]{\sphinxcrossref{\DUrole{hole}{record\_field}}}}}}}).

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For instance, when declaring the \sphinxcode{\sphinxupquote{\DUrole{name}{Setoid}}} structure above, the
\sphinxcode{\sphinxupquote{\DUrole{name}{Prf\_equiv}}} field declaration could be written as follows.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{\PYGZsh{}}\PYG{o}{[}\PYG{n}{canonical}\PYG{o}{=}\PYG{n}{no}\PYG{o}{]} \PYG{n}{Prf\PYGZus{}equiv} \PYG{o}{:} \PYG{n}{equivalence} \PYG{n}{Carrier} \PYG{n}{Equal}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
See {\hyperref[\detokenize{language/extensions/canonical:hierarchy-of-structures}]{\sphinxcrossref{\DUrole{std,std-ref}{Hierarchy of structures}}}} for a more realistic example.

\end{fulllineitems}\end{savenotes}

\index{Print Canonical Projections (command)@\spxentry{Print Canonical Projections}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/extensions/canonical:coq:cmd.Print-Canonical-Projections}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Canonical~Projections~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
This displays the list of global names that are components of some
canonical structure. For each of them, the canonical structure of
which it is a projection is indicated. If {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} are given as
its arguments, only the unification rules that involve or are
synthesized from simultaneously all given constants will be shown.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For instance, the above example gives the following output:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{k+kn}{Canonical} \PYG{k+kn}{Projections}\PYG{o}{.}
    \PYG{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{k+kn}{Canonical} \PYG{k+kn}{Projections} \PYG{n}{nat}\PYG{o}{.}
    \PYG{n}{nat} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{Carrier} \PYG{o}{(} \PYG{n}{nat\PYGZus{}setoid} \PYG{o}{)}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The last line in the first example would not show up if the
corresponding projection (namely \sphinxcode{\sphinxupquote{\DUrole{name}{Prf\_equiv}}}) were annotated as not
canonical, as described above.
\end{sphinxadmonition}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\subsubsection{Notation overloading}
\label{\detokenize{language/extensions/canonical:notation-overloading}}
\sphinxAtStartPar
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.

\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}

\sphinxAtStartPar
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).

\sphinxAtStartPar
Note that in practice the user may want to declare \sphinxcode{\sphinxupquote{EQ.obj}} as a
coercion, but we will not do that here.

\sphinxAtStartPar
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{==}}.

\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}

\sphinxAtStartPar
Still, no concrete type is in the \sphinxcode{\sphinxupquote{EQ}} class.

\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}

\sphinxAtStartPar
We amend that by equipping \sphinxcode{\sphinxupquote{nat}} with a comparison relation.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{nat\PYGZus{}eq} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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{n}{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{n}{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}

\sphinxAtStartPar
This last test shows that 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 with the key. In this
case we associate with 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.

\sphinxAtStartPar
Similarly, we could equip any other type with a comparison relation,
and use the \sphinxcode{\sphinxupquote{==}} notation on terms of this type.


\paragraph{Derived Canonical Structures}
\label{\detokenize{language/extensions/canonical:derived-canonical-structures}}
\sphinxAtStartPar
We know how to use \sphinxcode{\sphinxupquote{==}} on base types, like \sphinxcode{\sphinxupquote{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:

\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}

\sphinxAtStartPar
The error message is telling that Coq has no idea on how to compare
pairs of objects. The following construction is telling Coq exactly
how to do that.

\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{n}{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{n}{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}

\sphinxAtStartPar
Thanks to the \sphinxcode{\sphinxupquote{pair\_EQty}} declaration, 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.


\subsubsection{Hierarchy of structures}
\label{\detokenize{language/extensions/canonical:hierarchy-of-structures}}\label{\detokenize{language/extensions/canonical:id4}}
\sphinxAtStartPar
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{<=}} notation.

\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}

\sphinxAtStartPar
As before we register a canonical \sphinxcode{\sphinxupquote{LE}} class for \sphinxcode{\sphinxupquote{nat}}.

\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{n}{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{n}{nat} \PYG{n}{nat\PYGZus{}LEcl}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}LEty} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
And we enable Coq to relate pair of terms with \sphinxcode{\sphinxupquote{<=}}.

\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}

\sphinxAtStartPar
At the current stage we can use \sphinxcode{\sphinxupquote{==}} and \sphinxcode{\sphinxupquote{<=}} 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.

\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}

\sphinxAtStartPar
We need to define a new class that inherits from both \sphinxcode{\sphinxupquote{EQ}} and \sphinxcode{\sphinxupquote{LE}}.

\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{o}{\PYGZsh{}}\PYG{o}{[}\PYG{n}{canonical}\PYG{o}{=}\PYG{n}{no}\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{class\_of}} projection of the \sphinxcode{\sphinxupquote{type}} structure is annotated as \sphinxstyleemphasis{not canonical};
it plays no role in the search for instances.

\sphinxAtStartPar
Unfortunately there is still an obstacle to developing the algebraic
theory of this new class.

\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}

\sphinxAtStartPar
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 Coq does not see that an object of
the \sphinxcode{\sphinxupquote{LEQ}} class is also an object of the \sphinxcode{\sphinxupquote{LE}} class.

\sphinxAtStartPar
The following two constructions tell 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.

\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}

\sphinxAtStartPar
We can now formulate out first theorem on the objects of the \sphinxcode{\sphinxupquote{LEQ}}
structure.

\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}{goal}
      
      \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}{goals}\PYG{o}{.}


   \PYG{k+kn}{Qed}\PYG{o}{.}

   \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}{|}\PYG{o}{\PYGZhy{}} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{]}
\end{sphinxVerbatim}

\sphinxAtStartPar
Of course one would like to apply results proved in the algebraic
setting to any concrete instate of the algebraic structure.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Example} \PYG{n}{test\PYGZus{}algebraic} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{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{k+kn}{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}{goal}
      
      \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{k+kn}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Again one has to tell 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.

\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{n}{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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{k+kn}{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}{goal}
      
      \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{k+kn}{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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
Unfortunately, these declarations are very verbose. In the following
subsection we show how to make them more compact.

\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{n}{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{k+kn}{Example} \PYG{n}{test\PYGZus{}algebraic} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goals}\PYG{o}{.}


   \PYG{k+kn}{Qed}\PYG{o}{.}

   \PYG{k+kn}{Example} \PYG{n}{test\PYGZus{}algebraic2} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{*} \PYG{n}{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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{*} \PYG{n}{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{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}


\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}

\sphinxAtStartPar
Note that no direct proof of \sphinxcode{\sphinxupquote{n <= m \sphinxhyphen{}> m <= n \sphinxhyphen{}> 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 Coq performs automatically
while inferring canonical structures.


\paragraph{Compact declaration of Canonical Structures}
\label{\detokenize{language/extensions/canonical:compact-declaration-of-canonical-structures}}
\sphinxAtStartPar
We need some infrastructure for that.

\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}{ring\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{n}{phantom\PYGZus{}sind} \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{n}{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 | 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}{name}\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 | t1 \PYGZti{} t2 | 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}{name}\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}

\sphinxAtStartPar
To explain the notation \sphinxcode{\sphinxupquote{{[}find v | t1 \textasciitilde{} t2{]}}} let us pick one of its
instances: \sphinxcode{\sphinxupquote{{[}find e | EQ.obj e \textasciitilde{} T | "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"”.

\sphinxAtStartPar
The other utilities are used to ask 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 {[}\hyperlink{cite.zebibliography:id17}{MT13}{]}.

\sphinxAtStartPar
We now have all we need to create a compact “packager” to declare
instances of the \sphinxcode{\sphinxupquote{LEQ}} class.

\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}{|} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZti{}} \PYG{n}{T} \PYG{o}{|} \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}{|} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{o} \PYG{o}{\PYGZti{}} \PYG{n}{T} \PYG{o}{|} \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}{|} \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}{|} \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}{|} \PYG{n}{m} \PYG{o}{\PYGZti{}} \PYG{n}{m0} \PYG{o}{|} \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}

\sphinxAtStartPar
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 with 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 Coq.

\sphinxAtStartPar
\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 {[}\hyperlink{cite.zebibliography:id17}{MT13}{]}.

\sphinxAtStartPar
The declaration of canonical instances can now be way more compact:

\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{n}{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}
\end{sphinxVerbatim}

\sphinxAtStartPar
Error messages are also quite intelligible (if one skips to the end of
the message).

\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{n}{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}


\subsection{Program}
\label{\detokenize{addendum/program:program}}\label{\detokenize{addendum/program:programs}}\label{\detokenize{addendum/program::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
\sphinxAtStartPar
Matthieu Sozeau

\end{description}\end{quote}

\sphinxAtStartPar
We present here the \sphinxstylestrong{Program} tactic commands, used to build
certified Coq programs, elaborating them from their algorithmic
skeleton and a rich specification {[}\hyperlink{cite.zebibliography:id48}{Soz07}{]}. 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 Coq proof apparatus. This is done using
a technique originating from the “Predicate subtyping” mechanism of
PVS {[}\hyperlink{cite.zebibliography:id47}{ROS98}{]}, 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 Coq term. \sphinxstylestrong{Program} replaces the \sphinxstylestrong{Program} tactic by Catherine
Parent {[}\hyperlink{cite.zebibliography:id44}{Par95}{]} which had a similar goal but is no longer maintained.

\sphinxAtStartPar
The languages available as input are currently restricted to Coq’s
term language, but may be extended to OCaml, Haskell and
others in the future. We use the same syntax as 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 Coq terms. The interpretation process may produce some proof
obligations which need to be resolved to create the final term.


\subsubsection{Elaborating programs}
\label{\detokenize{addendum/program:elaborating-programs}}\label{\detokenize{addendum/program:id4}}
\sphinxAtStartPar
The main difference from 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}{|} \DUrole{name}{P}\DUrole{operator}{\}}}} for any well\sphinxhyphen{}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.

\sphinxAtStartPar
Another distinction is the treatment of pattern matching. Apart from
the following differences, it is equivalent to the standard match
operation (see {\hyperref[\detokenize{language/extensions/match:extendedpatternmatching}]{\sphinxcrossref{\DUrole{std,std-ref}{Extended pattern matching}}}}).
\begin{itemize}
\item {} 
\sphinxAtStartPar
Generation of equalities. A match expression is always generalized
by the corresponding equality. As an example, the expression:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
match x with
| 0 =\PYGZgt{} t
| S n =\PYGZgt{} u
end.
\end{sphinxVerbatim}

\sphinxAtStartPar
will be first rewritten to:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(match x as y return (x = y \PYGZhy{}\PYGZgt{} \PYGZus{}) with
| 0 =\PYGZgt{} fun H : x = 0 \PYGZhy{}\PYGZgt{} t
| S n =\PYGZgt{} fun H : x = S n \PYGZhy{}\PYGZgt{} u
end) (eq\PYGZus{}refl x).
\end{sphinxVerbatim}

\sphinxAtStartPar
This permits to get the proper equalities in the context of proof
obligations inside clauses, without which reasoning is very limited.

\item {} 
\sphinxAtStartPar
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{operator}{∀} \DUrole{name}{p}\DUrole{operator}{,} \DUrole{operator}{\_} \DUrole{operator}{<>} \DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{p}\DUrole{operator}{)}}}.

\item {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
There are flags to control the generation of equalities and
coercions.
\index{Program Cases (flag)@\spxentry{Program Cases}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:flag.Program-Cases}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Cases}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls the special treatment of pattern matching generating equalities
and disequalities when using \sphinxstylestrong{Program} (it is on by default). All
pattern\sphinxhyphen{}matches and let\sphinxhyphen{}patterns are handled using the standard algorithm
of Coq (see {\hyperref[\detokenize{language/extensions/match:extendedpatternmatching}]{\sphinxcrossref{\DUrole{std,std-ref}{Extended pattern matching}}}}) when this flag is
deactivated.

\end{fulllineitems}\end{savenotes}

\index{Program Generalized Coercion (flag)@\spxentry{Program Generalized Coercion}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls the coercion of general inductive types when using \sphinxstylestrong{Program}
(the flag is on by default). Coercion of subset types and pairs is still
active in this case.

\end{fulllineitems}\end{savenotes}

\index{Program Mode (flag)@\spxentry{Program Mode}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:flag.Program-Mode}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Mode}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} enables the program mode, in which 1) typechecking allows subset coercions and
2) the elaboration of pattern matching of {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} and
{\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} acts as if the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute has been
used, generating obligations if there are unresolved holes after
typechecking.

\end{fulllineitems}\end{savenotes}

\index{program (attribute)@\spxentry{program}\spxextra{attribute}}\index{Program (attribute)@\spxentry{Program}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:attr.program}}\phantomsection\label{\detokenize{addendum/program:coq:attr.Program}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{program\DUrole{repeat-wrapper}{\DUrole{repeat}{=~\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{boolean attribute}}}} allows using or disabling the Program mode on a specific
definition.  An alternative and commonly used syntax is to use the legacy \sphinxcode{\sphinxupquote{Program}}
prefix (cf. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-legacy_attr}]{\sphinxcrossref{\DUrole{hole}{legacy\_attr}}}}}}}) as it is elsewhere in this chapter.

\end{fulllineitems}\end{savenotes}



\paragraph{Syntactic control over equalities}
\label{\detokenize{addendum/program:syntactic-control-over-equalities}}\label{\detokenize{addendum/program:syntactic-control}}
\sphinxAtStartPar
To give more control over the generation of equalities, the
type checker will fall back directly to Coq’s usual typing of dependent
pattern matching if a \sphinxcode{\sphinxupquote{return}} or \sphinxcode{\sphinxupquote{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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Program} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Program} \PYG{k+kn}{Definition} \PYG{n}{id} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZob{}} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{|} \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{n}{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{n}{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{n}{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{n}{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}

\sphinxAtStartPar
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{keyword}{'}\DUrole{operator}{(}\DUrole{name}{x1}\DUrole{operator}{,...,} \DUrole{name}{xn}\DUrole{operator}{)} \DUrole{operator}{:=} \DUrole{name}{t} \DUrole{keyword}{in} \DUrole{name}{b}}}.

\sphinxAtStartPar
The next two commands are similar to their standard counterparts
{\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} and {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}
in that they define {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}}. However, they may require the user to
prove some goals to construct the final definitions.


\paragraph{Program Definition}
\label{\detokenize{addendum/program:program-definition}}\label{\detokenize{addendum/program:id5}}
\sphinxAtStartPar
A {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} command with the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute types
the value term in Russell and generates proof
obligations. Once solved using the commands shown below, it binds the
final Coq term to the name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in the global environment.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Program Definition {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}

\sphinxAtStartPar
Interprets the type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}, potentially generating proof
obligations to be resolved. Once done with them, we have a Coq
type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{0}}$}}}}}}}. It then elaborates the preterm \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} into a Coq
term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}}}}}, checking that the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}}}}} is coercible to
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{0}}$}}}}}}}, and registers \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} as being of type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type$_{\text{0}}$}}}}}}} once the
set of obligations generated during the interpretation of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{0}}$}}}}}}}
and the aforementioned coercion derivation are solved.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
Sections {\hyperref[\detokenize{proofs/writing-proofs/equality:controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reduction strategies and the conversion algorithm}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}




\paragraph{Program Fixpoint}
\label{\detokenize{addendum/program:program-fixpoint}}\label{\detokenize{addendum/program:id6}}
\sphinxAtStartPar
A {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} command with the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute may also generate obligations. It works
with mutually recursive definitions too.  For example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Program} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Program} \PYG{k+kn}{Fixpoint} \PYG{n}{div2} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZob{}} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{|} \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}{|} \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}{|} \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}

\sphinxAtStartPar
The {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} command may include an optional \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}}} annotation, which can be:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{name}{measure} \DUrole{name}{f} \DUrole{name}{R}}} 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 term
\sphinxcode{\sphinxupquote{\DUrole{name}{R}}} is a relation on \sphinxcode{\sphinxupquote{\DUrole{name}{X}}}. \sphinxcode{\sphinxupquote{\DUrole{name}{X}}} defaults to \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{R}}}
to \sphinxcode{\sphinxupquote{\DUrole{name}{lt}}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{name}{wf} \DUrole{name}{R} \DUrole{name}{x}}} which is equivalent to \sphinxcode{\sphinxupquote{\DUrole{name}{measure} \DUrole{name}{x} \DUrole{name}{R}}}.

\end{itemize}

\sphinxAtStartPar
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).

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Obligation} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{p}\PYG{o}{,} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
One can use a well\sphinxhyphen{}founded order or a measure as termination orders
using the syntax:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Program} \PYG{k+kn}{Fixpoint} \PYG{n}{div2} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{nat} \PYG{o}{|} \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}{|} \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}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{caution}{Caution:}
\sphinxAtStartPar
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\sphinxhyphen{}
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.

\sphinxAtStartPar
No such problems arise when using measures or well\sphinxhyphen{}founded recursion.
\end{sphinxadmonition}


\paragraph{Program Lemma}
\label{\detokenize{addendum/program:program-lemma}}\label{\detokenize{addendum/program:id7}}
\sphinxAtStartPar
A {\hyperref[\detokenize{language/core/definitions:coq:cmd.Lemma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Lemma}}}}} command with the {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute uses the Russell
language to type statements of logical
properties. It generates obligations, tries to solve them
automatically and fails if some unsolved obligations remain. In this
case, one can first define the lemma’s statement using {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}
and use it as the goal afterwards. Otherwise the proof
will be started with the elaborated version as a goal. The
{\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} attribute can similarly be used with
{\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}}, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Hypothesis}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hypothesis}}}}}, {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}} etc.


\subsubsection{Solving obligations}
\label{\detokenize{addendum/program:solving-obligations}}\label{\detokenize{addendum/program:id8}}
\sphinxAtStartPar
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 (command)@\spxentry{Obligation Tactic}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.Obligation-Tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Obligation~Tactic~:=~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}
\sphinxAtStartPar
Sets the default obligation solving tactic applied to all obligations
automatically, whether to solve them or when starting to prove one,
e.g. using {\hyperref[\detokenize{addendum/program:coq:cmd.Next-Obligation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Next Obligation}}}}}.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} and {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attributes.
{\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} makes the setting last only for the current
module. {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} is the default inside sections while {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}}
otherwise.

\end{fulllineitems}\end{savenotes}

\index{Show Obligation Tactic (command)@\spxentry{Show Obligation Tactic}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Displays the current default tactic.

\end{fulllineitems}\end{savenotes}

\index{Obligations (command)@\spxentry{Obligations}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Displays all remaining obligations.

\end{fulllineitems}\end{savenotes}

\index{Obligation (command)@\spxentry{Obligation}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.Obligation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Obligation~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{of~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Start the proof of obligation {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Next Obligation (command)@\spxentry{Next Obligation}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Start the proof of the next unsolved obligation.

\end{fulllineitems}\end{savenotes}

\index{Solve Obligations (command)@\spxentry{Solve Obligations}\spxextra{command}}

\begin{savenotes}\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}{of~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Tries to solve each obligation of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} using the given {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} or the default one.

\end{fulllineitems}\end{savenotes}

\index{Solve All Obligations (command)@\spxentry{Solve All Obligations}\spxextra{command}}

\begin{savenotes}\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~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Tries to solve each obligation of every program using the given
tactic or the default one (useful for mutually recursive definitions).

\end{fulllineitems}\end{savenotes}

\index{Admit Obligations (command)@\spxentry{Admit Obligations}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Admits all obligations (of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}).

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Does not work with structurally recursive programs.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{Preterm (command)@\spxentry{Preterm}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Shows the term that will be fed to the kernel once the obligations
are solved. Useful for debugging.

\end{fulllineitems}\end{savenotes}

\index{Transparent Obligations (flag)@\spxentry{Transparent Obligations}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:flag.Transparent-Obligations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Transparent~Obligations}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} 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}\end{savenotes}


\sphinxAtStartPar
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.


\subsubsection{Frequently Asked Questions}
\label{\detokenize{addendum/program:frequently-asked-questions}}\label{\detokenize{addendum/program:program-faq}}\index{Ill\sphinxhyphen{}formed recursive definition (error)@\spxentry{Ill\sphinxhyphen{}formed recursive definition}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:exn.Ill-formed-recursive-definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ill\sphinxhyphen{}formed~recursive~definition.}}}}
\sphinxAtStartPar
This error can happen when one tries to define a function by structural
recursion on a subset object, which means the Coq function looks like:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Program Fixpoint f (x : A | P) := match x with A b =\PYGZgt{} f b end.
\end{sphinxVerbatim}

\sphinxAtStartPar
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 | P\}}}.  Hence the definition is
rejected by the guardedness condition checker.  However one can use
wellfounded recursion on subset objects like this:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Program Fixpoint f (x : A | P) \PYGZob{} measure (size x) \PYGZcb{} :=
  match x with A b =\PYGZgt{} f b end.
\end{sphinxVerbatim}

\sphinxAtStartPar
One will then just have to prove that the measure decreases at each
recursive call. There are three drawbacks though:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
A measure function has to be defined;

\item {} 
\sphinxAtStartPar
The reduction is a little more involved, although it works well
using lazy evaluation;

\item {} 
\sphinxAtStartPar
Mutual recursion on the underlying inductive type isn’t possible
anymore, but nested mutual recursion is always possible.

\end{enumerate}

\end{fulllineitems}\end{savenotes}



\subsection{Commands}
\label{\detokenize{proof-engine/vernacular-commands:commands}}\label{\detokenize{proof-engine/vernacular-commands:vernacularcommands}}\label{\detokenize{proof-engine/vernacular-commands::doc}}

\subsubsection{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 (command)@\spxentry{Print}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Print}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~\DUrole{repeat-wrapper}{\DUrole{repeat}{Term}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-univ_name_list}]{\sphinxcrossref{\DUrole{hole}{univ\_name\_list}}}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-univ_name_list}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-univ_name_list}]{\sphinxcrossref{\DUrole{hole}{univ\_name\_list}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{@\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{*}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Displays definitions of terms, including opaque terms, for the object \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}.
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Term}}} \sphinxhyphen{} a syntactic marker to allow printing a term
that is the same as one of the various \sphinxcode{\sphinxupquote{\DUrole{notation}{Print}}} commands.  For example,
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print All}}}}} is a different command, while \sphinxcode{\sphinxupquote{\DUrole{notation}{Print Term All}}} shows
information on the object whose name is "\sphinxcode{\sphinxupquote{\DUrole{notation}{All}}}".

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-univ_name_list}]{\sphinxcrossref{\DUrole{hole}{univ\_name\_list}}}}}}} \sphinxhyphen{} locally renames the
polymorphic universes of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}.
The name \sphinxcode{\sphinxupquote{\_}} means the usual name is printed.

\end{itemize}
\index{‘qualid’ not a defined object (error)@\spxentry{‘qualid’ not a defined object}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn._u2018qualid_u2019-not-a-defined-object}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~not~a~defined~object.}}}}
\end{fulllineitems}\end{savenotes}

\index{Universe instance should have length ‘natural’ (error)@\spxentry{Universe instance should have length ‘natural’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.Universe-instance-should-have-length-_u2018natural_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~instance~should~have~length~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{This object does not support universe names (error)@\spxentry{This object does not support universe names}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Print All (command)@\spxentry{Print All}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This command displays information about the current state of the
environment, including sections and modules.

\end{fulllineitems}\end{savenotes}

\index{Inspect (command)@\spxentry{Inspect}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Inspect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Inspect~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This command displays the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} last objects of the
current environment, including sections and modules.

\end{fulllineitems}\end{savenotes}

\index{Print Section (command)@\spxentry{Print Section}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Section}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Section~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Displays the objects defined since the beginning of the section named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.

\end{fulllineitems}\end{savenotes}



\subsubsection{Query commands}
\label{\detokenize{proof-engine/vernacular-commands:query-commands}}
\sphinxAtStartPar
Unlike other commands, \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-query_command}}\sphinxcode{\sphinxupquote{query\_command}}}s may be prefixed with
a goal selector (\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}:}}}) to specify which goals it applies to.
If no selector is provided,
the command applies to the current goal.  If no proof is open, then the command only applies
to accessible objects.  (see Section {\hyperref[\detokenize{proof-engine/tactics:invocation-of-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Invocation of tactics}}}}).

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Eval}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Compute}}}}} are also {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-query_command}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{query\_command}}}}}s, which are
described elsewhere
\index{About (command)@\spxentry{About}\spxextra{command}}

\begin{savenotes}\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{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-univ_name_list}]{\sphinxcrossref{\DUrole{hole}{univ\_name\_list}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Displays information about the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} object, which,
if a proof is open,  may be a hypothesis of the selected goal,
or an accessible theorem, axiom, etc.:
its kind (module, constant, assumption, inductive,
constructor, abbreviation, …), long name, type, implicit arguments and
argument scopes (as set in the definition of {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}} or
subsequently with the {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command). It does not print the body of definitions or proofs.

\end{fulllineitems}\end{savenotes}

\index{Check (command)@\spxentry{Check}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
Displays the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. When called in proof mode, the
term is checked in the local context of the selected goal.

\end{fulllineitems}\end{savenotes}

\index{Search (command)@\spxentry{Search}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{inside}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{outside}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This command can be used to filter the goal and the global context
to retrieve objects whose name or type satisfies a number of
conditions.  Library files that were not loaded with {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}}
are not considered.  The {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:table.Search-Blacklist}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search Blacklist}}}}} table can also
be used to exclude some things from all calls to {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}}.

\sphinxAtStartPar
The output of the command is a list of qualified identifiers and
their types.  If the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Search-Output-Name-Only}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search Output Name Only}}}}} flag is on,
the types are omitted.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_item}]{\sphinxcrossref{\DUrole{hole}{search\_item}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Multiple \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_item}]{\sphinxcrossref{\DUrole{hole}{search\_item}}}}}}}s can be combined into a complex
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}}}:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}}}}] \leavevmode
\sphinxAtStartPar
Excludes the objects that would be filtered by
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}}}.  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-disambiguate-notation}]{\sphinxcrossref{\DUrole{std,std-ref}{this example}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}\DUrole{notation-sup}{+}} | ... | \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_query}]{\sphinxcrossref{\DUrole{hole}{search\_query}}}}}\DUrole{notation-sup}{+}} {]}}}}}] \leavevmode
\sphinxAtStartPar
This is a disjunction of conjunctions of queries.  A simple
conjunction can be expressed by having a single disjunctive
branch.  For a conjunction at top\sphinxhyphen{}level, the surrounding
brackets are not required.

\end{description}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-search_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-search_item}]{\sphinxcrossref{\DUrole{hole}{search\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{head}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{hyp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{concl}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{headhyp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{headconcl}} :}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{head}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{hyp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{concl}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{headhyp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{headconcl}} :}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{is : {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-logical_kind}]{\sphinxcrossref{\DUrole{hole}{logical\_kind}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Searched objects can be filtered by patterns, by the constants they
contain (identified by their name or a notation) and by their
names.
The location of the pattern or constant within a term
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}}}}] \leavevmode
\sphinxAtStartPar
Search for objects whose type contains a subterm matching the
pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}}}.  Holes of the pattern are indicated by
\sphinxcode{\sphinxupquote{\_}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.  If the same \sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} occurs more than
once in the pattern, all occurrences in the subterm must be
identical.  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-pattern}]{\sphinxcrossref{\DUrole{std,std-ref}{this example}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode\begin{itemize}
\item {} 
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} is a substring of a valid identifier and no
\sphinxcode{\sphinxupquote{\DUrole{notation}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}} is provided, search for objects whose name
contains \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}.  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-part-ident}]{\sphinxcrossref{\DUrole{std,std-ref}{this example}}}}.

\item {} 
\sphinxAtStartPar
Otherwise, search for objects
whose type contains the reference that this string,
interpreted as a notation, is attached to (as described in
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}).  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-by-notation}]{\sphinxcrossref{\DUrole{std,std-ref}{this example}}}}.

\end{itemize}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
To refer to a string used in a notation that is a substring of a valid identifier,
put it between single quotes or explicitly provide a scope.
See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-disambiguate-notation}]{\sphinxcrossref{\DUrole{std,std-ref}{this example}}}}.
\end{sphinxadmonition}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{hyp:}}}}] \leavevmode
\sphinxAtStartPar
The provided pattern or reference is matched against any subterm
of an hypothesis of the type of the objects.  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-hyp}]{\sphinxcrossref{\DUrole{std,std-ref}{this
example}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{headhyp:}}}}] \leavevmode
\sphinxAtStartPar
The provided pattern or reference is matched against the
subterms in head position (any partial applicative subterm) of
the hypotheses of the type of the objects.  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-hyp}]{\sphinxcrossref{\DUrole{std,std-ref}{the
previous example}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{concl:}}}}] \leavevmode
\sphinxAtStartPar
The provided pattern or reference is matched against any subterm
of the conclusion of the type of the objects.  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-concl}]{\sphinxcrossref{\DUrole{std,std-ref}{this
example}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{headconcl:}}}}] \leavevmode
\sphinxAtStartPar
The provided pattern or reference is matched against the
subterms in head position (any partial applicative subterm) of
the conclusion of the type of the objects.  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-concl}]{\sphinxcrossref{\DUrole{std,std-ref}{the
previous example}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{head:}}}}] \leavevmode
\sphinxAtStartPar
This is simply the union between \sphinxcode{\sphinxupquote{headconcl:}} and \sphinxcode{\sphinxupquote{headhyp:}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{is: {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-logical_kind}]{\sphinxcrossref{\DUrole{hole}{logical\_kind}}}}}}}}] \leavevmode\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-logical_kind}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-logical_kind}]{\sphinxcrossref{\DUrole{hole}{logical\_kind}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/definitions:grammar-token-thm_token}]{\sphinxcrossref{\DUrole{hole}{thm\_token}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-assumption_token}]{\sphinxcrossref{\DUrole{hole}{assumption\_token}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Definition}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Example}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Context}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Primitive}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Coercion}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Instance}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Scheme}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Canonical}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{SubClass}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Field}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Method}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Filters objects by the keyword that was used to define them
(\sphinxcode{\sphinxupquote{Theorem}}, \sphinxcode{\sphinxupquote{Lemma}}, \sphinxcode{\sphinxupquote{Axiom}}, \sphinxcode{\sphinxupquote{Variable}}, \sphinxcode{\sphinxupquote{Context}},
\sphinxcode{\sphinxupquote{Primitive}}...) or its status (\sphinxcode{\sphinxupquote{Coercion}}, \sphinxcode{\sphinxupquote{Instance}}, \sphinxcode{\sphinxupquote{Scheme}},
\sphinxcode{\sphinxupquote{Canonical}}, \sphinxcode{\sphinxupquote{SubClass}}, Field` for record fields, \sphinxcode{\sphinxupquote{Method}} for class
fields).  Note that \sphinxcode{\sphinxupquote{Coercion}}s, \sphinxcode{\sphinxupquote{Canonical Structure}}s, Instance`s and \sphinxcode{\sphinxupquote{Scheme}}s can be
defined without using those keywords.  See {\hyperref[\detokenize{proof-engine/vernacular-commands:search-by-keyword}]{\sphinxcrossref{\DUrole{std,std-ref}{this example}}}}.

\end{description}

\sphinxAtStartPar
Additional clauses:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{inside \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}} \sphinxhyphen{} limit the search to the specified modules

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{outside \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}} \sphinxhyphen{} exclude the specified modules from the search

\end{itemize}
\index{Module/section ‘qualid’ not found (error)@\spxentry{Module/section ‘qualid’ not found}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.Module/section-_u2018qualid_u2019-not-found}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module/section~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~not~found.}}}}
\sphinxAtStartPar
There is no constant in the environment named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
is in an \sphinxcode{\sphinxupquote{inside}} or \sphinxcode{\sphinxupquote{outside}} clause.

\end{fulllineitems}\end{savenotes}

\phantomsection\label{\detokenize{proof-engine/vernacular-commands:search-pattern}}
\begin{sphinxadmonition}{note}{Example: Searching for a pattern}

\sphinxAtStartPar
We can repeat meta\sphinxhyphen{}variables to narrow down the search.  Here,
we are looking for commutativity lemmas.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{?}\PYG{n}{n} \PYG{o}{?}\PYG{n}{m} \PYG{o}{=} \PYG{o}{\PYGZus{}} \PYG{o}{?}\PYG{n}{m} \PYG{o}{?}\PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{land\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{land} \PYG{n}{a} \PYG{n}{b} \PYG{o}{=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{land} \PYG{n}{b} \PYG{n}{a}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lor\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lor} \PYG{n}{a} \PYG{n}{b} \PYG{o}{=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lor} \PYG{n}{b} \PYG{n}{a}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lxor\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lxor} \PYG{n}{a} \PYG{n}{b} \PYG{o}{=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lxor} \PYG{n}{b} \PYG{n}{a}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lcm\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lcm} \PYG{n}{a} \PYG{n}{b} \PYG{o}{=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lcm} \PYG{n}{b} \PYG{n}{a}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{min\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{min} \PYG{n}{n} \PYG{n}{m} \PYG{o}{=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{min} \PYG{n}{m} \PYG{n}{n}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{gcd\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{gcd} \PYG{n}{n} \PYG{n}{m} \PYG{o}{=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{gcd} \PYG{n}{m} \PYG{n}{n}
    \PYG{n}{Bool}\PYG{o}{.}\PYG{n}{xorb\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{b} \PYG{n}{b\PYGZsq{}} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{,} \PYG{n}{xorb} \PYG{n}{b} \PYG{n}{b\PYGZsq{}} \PYG{o}{=} \PYG{n}{xorb} \PYG{n}{b\PYGZsq{}} \PYG{n}{b}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{max\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{max} \PYG{n}{n} \PYG{n}{m} \PYG{o}{=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{max} \PYG{n}{m} \PYG{n}{n}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{mul\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{n}{m} \PYG{o}{=} \PYG{n}{m} \PYG{o}{*} \PYG{n}{n}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{=} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n}
    \PYG{n}{Bool}\PYG{o}{.}\PYG{n}{orb\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{,} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b2}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{bool} \PYG{o}{=} \PYG{o}{(}\PYG{n}{b2} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b1}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{bool}
    \PYG{n}{Bool}\PYG{o}{.}\PYG{n}{andb\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{,} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{bool} \PYG{o}{=} \PYG{o}{(}\PYG{n}{b2} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b1}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{eqb\PYGZus{}sym}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{n}{x} \PYG{o}{=}\PYG{o}{?} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{y} \PYG{o}{=}\PYG{o}{?} \PYG{n}{x}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:search-part-ident}}
\begin{sphinxadmonition}{note}{Example: Searching for part of an identifier}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZus{}assoc}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{or\PYGZus{}assoc}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{B}\PYG{o}{)} \PYG{o}{\PYGZbs{}/} \PYG{n}{C} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{B} \PYG{o}{\PYGZbs{}/} \PYG{n}{C}
    \PYG{n}{and\PYGZus{}assoc}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{o}{(}\PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C}
    \PYG{n}{eq\PYGZus{}trans\PYGZus{}assoc}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{[}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{]} \PYG{o}{[}\PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{n}{t} \PYG{o}{:} \PYG{n}{A}\PYG{o}{]} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{e\PYGZsq{}} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}\PYG{o}{)} \PYG{o}{(}\PYG{n}{e\PYGZsq{}\PYGZsq{}} \PYG{o}{:} \PYG{n}{z} \PYG{o}{=} \PYG{n}{t}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{eq\PYGZus{}trans} \PYG{n}{e} \PYG{o}{(}\PYG{n}{eq\PYGZus{}trans} \PYG{n}{e\PYGZsq{}} \PYG{n}{e\PYGZsq{}\PYGZsq{}}\PYG{o}{)} \PYG{o}{=} \PYG{n}{eq\PYGZus{}trans} \PYG{o}{(}\PYG{n}{eq\PYGZus{}trans} \PYG{n}{e} \PYG{n}{e\PYGZsq{}}\PYG{o}{)} \PYG{n}{e\PYGZsq{}\PYGZsq{}}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:search-by-notation}}
\begin{sphinxadmonition}{note}{Example: Searching for a reference by notation}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{+}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{plus\PYGZus{}O\PYGZus{}n}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n}
    \PYG{n}{plus\PYGZus{}n\PYGZus{}O}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0}
    \PYG{n}{plus\PYGZus{}n\PYGZus{}Sm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{plus\PYGZus{}Sn\PYGZus{}m}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{S} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)}
    \PYG{n}{mult\PYGZus{}n\PYGZus{}Sm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{*} \PYG{n}{S} \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{n}{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\PYGZus{}rect\PYGZus{}plus}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{nat\PYGZus{}rect} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{A}\PYG{o}{)} \PYG{n}{x} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{f}\PYG{o}{)} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=}
      \PYG{n}{nat\PYGZus{}rect} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{A}\PYG{o}{)}
        \PYG{o}{(}\PYG{n}{nat\PYGZus{}rect} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{A}\PYG{o}{)} \PYG{n}{x} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{f}\PYG{o}{)} \PYG{n}{m}\PYG{o}{)} 
        \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{f}\PYG{o}{)} \PYG{n}{n}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:search-disambiguate-notation}}
\begin{sphinxadmonition}{note}{Example: Disambiguating between part of identifier and notation}

\sphinxAtStartPar
In this example, we show two ways of searching for all the
objects whose type contains \sphinxcode{\sphinxupquote{Nat.modulo}} but which do not
contain the substring "mod".

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}mod\PYGZsq{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{\PYGZhy{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{mod}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{bit0\PYGZus{}eqb}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{o}{(}\PYG{n}{a} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{=}\PYG{o}{?} \PYG{l+m+mi}{1}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{land\PYGZus{}ones}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{land} \PYG{n}{a} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{ones} \PYG{n}{n}\PYG{o}{)} \PYG{o}{=} \PYG{n}{a} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{div\PYGZus{}exact}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{b} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b} \PYG{o}{*} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{a} \PYG{n}{mod} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}spec\PYGZsq{}}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{b2n} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{n}{n}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}\PYG{o}{)} \PYG{n}{mod} \PYG{l+m+mi}{2}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{pow\PYGZus{}div\PYGZus{}l}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{n}{c} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{b} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{a} \PYG{n}{mod} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZca{}} \PYG{n}{c} \PYG{o}{=} \PYG{n}{a} \PYG{o}{\PYGZca{}} \PYG{n}{c} \PYG{o}{/} \PYG{n}{b} \PYG{o}{\PYGZca{}} \PYG{n}{c}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}eqb}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{n}{n} \PYG{o}{=} \PYG{o}{(}\PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}\PYG{o}{)} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{=}\PYG{o}{?} \PYG{l+m+mi}{1}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}false}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{n}{n} \PYG{o}{=} \PYG{n+nb+bp}{false} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}\PYG{o}{)} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}true}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{n}{n} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}\PYG{o}{)} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{1}

\PYG{k+kn}{Search} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{mod}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{\PYGZpc{}}\PYG{n}{nat} \PYG{o}{\PYGZhy{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{mod}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{bit0\PYGZus{}eqb}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{o}{(}\PYG{n}{a} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{=}\PYG{o}{?} \PYG{l+m+mi}{1}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{land\PYGZus{}ones}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{land} \PYG{n}{a} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{ones} \PYG{n}{n}\PYG{o}{)} \PYG{o}{=} \PYG{n}{a} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{div\PYGZus{}exact}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{b} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b} \PYG{o}{*} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{a} \PYG{n}{mod} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}spec\PYGZsq{}}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{b2n} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{n}{n}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}\PYG{o}{)} \PYG{n}{mod} \PYG{l+m+mi}{2}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{pow\PYGZus{}div\PYGZus{}l}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{n}{c} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{b} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{a} \PYG{n}{mod} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZca{}} \PYG{n}{c} \PYG{o}{=} \PYG{n}{a} \PYG{o}{\PYGZca{}} \PYG{n}{c} \PYG{o}{/} \PYG{n}{b} \PYG{o}{\PYGZca{}} \PYG{n}{c}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}eqb}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{n}{n} \PYG{o}{=} \PYG{o}{(}\PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}\PYG{o}{)} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{=}\PYG{o}{?} \PYG{l+m+mi}{1}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}false}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{n}{n} \PYG{o}{=} \PYG{n+nb+bp}{false} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}\PYG{o}{)} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}true}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{n}{n} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{\PYGZca{}} \PYG{n}{n}\PYG{o}{)} \PYG{n}{mod} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{1}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:search-hyp}}
\begin{sphinxadmonition}{note}{Example: Search in hypotheses}

\sphinxAtStartPar
The following search shows the objects whose type contains
\sphinxcode{\sphinxupquote{bool}} in an hypothesis as a strict subterm only:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{n}{hyp}\PYG{o}{:}\PYG{n}{bool} \PYG{o}{\PYGZhy{}}\PYG{n}{headhyp}\PYG{o}{:}\PYG{n}{bool}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{bitwise}\PYG{o}{:} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{of\PYGZus{}bits}\PYG{o}{:}
      \PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{n}{bool}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{byte}
    \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{to\PYGZus{}bits\PYGZus{}of\PYGZus{}bits}\PYG{o}{:}
      \PYG{k}{forall}
        \PYG{n}{b} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{n}{bool}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{to\PYGZus{}bits} \PYG{o}{(}\PYG{n}{Byte}\PYG{o}{.}\PYG{n}{of\PYGZus{}bits} \PYG{n}{b}\PYG{o}{)} \PYG{o}{=} \PYG{n}{b}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:search-concl}}
\begin{sphinxadmonition}{note}{Example: Search in conclusion}

\sphinxAtStartPar
The following search shows the objects whose type contains \sphinxcode{\sphinxupquote{bool}}
in the conclusion as a strict subterm only:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{n}{concl}\PYG{o}{:}\PYG{n}{bool} \PYG{o}{\PYGZhy{}}\PYG{n}{headconcl}\PYG{o}{:}\PYG{n}{bool}\PYG{o}{.}
    \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{to\PYGZus{}bits}\PYG{o}{:}
      \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{byte} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{n}{bool}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
    \PYG{n}{andb\PYGZus{}prop}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{,} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{bool} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{a} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{/\PYGZbs{}} \PYG{n}{b} \PYG{o}{=} \PYG{n+nb+bp}{true}
    \PYG{n}{andb\PYGZus{}true\PYGZus{}intro}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{[}\PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{]}\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{n}{bool} \PYG{o}{=} \PYG{n+nb+bp}{true}
    \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{to\PYGZus{}bits\PYGZus{}of\PYGZus{}bits}\PYG{o}{:}
      \PYG{k}{forall}
        \PYG{n}{b} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{o}{(}\PYG{n}{bool} \PYG{o}{*} \PYG{n}{bool}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{Byte}\PYG{o}{.}\PYG{n}{to\PYGZus{}bits} \PYG{o}{(}\PYG{n}{Byte}\PYG{o}{.}\PYG{n}{of\PYGZus{}bits} \PYG{n}{b}\PYG{o}{)} \PYG{o}{=} \PYG{n}{b}
    \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{n}{bool} \PYG{o}{|} \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{}}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:search-by-keyword}}
\begin{sphinxadmonition}{note}{Example: Search by keyword or status}

\sphinxAtStartPar
The following search shows the definitions whose type is a \sphinxcode{\sphinxupquote{nat}}
or a function which returns a \sphinxcode{\sphinxupquote{nat}} and the lemmas about \sphinxcode{\sphinxupquote{+}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{o}{[} \PYG{k}{is}\PYG{o}{:}\PYG{k+kn}{Definition} \PYG{n}{headconcl}\PYG{o}{:}\PYG{n}{nat} \PYG{o}{|} \PYG{k}{is}\PYG{o}{:}\PYG{k+kn}{Lemma} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{o}{]}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{two}\PYG{o}{:} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{zero}\PYG{o}{:} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{one}\PYG{o}{:} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{succ}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{log2}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{sqrt}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{square}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{double}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{pred}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{ldiff}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{tail\PYGZus{}mul}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{land}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{div}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{modulo}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lor}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{lxor}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{of\PYGZus{}hex\PYGZus{}uint}\PYG{o}{:} \PYG{n}{Hexadecimal}\PYG{o}{.}\PYG{n}{uint} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{of\PYGZus{}uint}\PYG{o}{:} \PYG{n}{Decimal}\PYG{o}{.}\PYG{n}{uint} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{of\PYGZus{}num\PYGZus{}uint}\PYG{o}{:} \PYG{n}{Number}\PYG{o}{.}\PYG{n}{uint} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{length}\PYG{o}{:} \PYG{k}{forall} \PYG{o}{[}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{]}\PYG{o}{,} \PYG{n}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{plus\PYGZus{}n\PYGZus{}O}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0}
    \PYG{n}{plus\PYGZus{}O\PYGZus{}n}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n}
    \PYG{n}{plus\PYGZus{}n\PYGZus{}Sm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{plus\PYGZus{}Sn\PYGZus{}m}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{S} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)}
    \PYG{n}{mult\PYGZus{}n\PYGZus{}Sm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{*} \PYG{n}{S} \PYG{n}{m}
\end{sphinxVerbatim}

\sphinxAtStartPar
The following search shows the instances whose type includes the
classes \sphinxcode{\sphinxupquote{Reflexive}} or \sphinxcode{\sphinxupquote{Symmetric}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{k}{is}\PYG{o}{:}\PYG{k+kn}{Instance} \PYG{o}{[} \PYG{n}{Reflexive} \PYG{o}{|} \PYG{n}{Symmetric} \PYG{o}{]}\PYG{o}{.}
    \PYG{n}{iff\PYGZus{}Symmetric}\PYG{o}{:} \PYG{n}{Symmetric} \PYG{n}{iff}
    \PYG{n}{iff\PYGZus{}Reflexive}\PYG{o}{:} \PYG{n}{Reflexive} \PYG{n}{iff}
    \PYG{n}{impl\PYGZus{}Reflexive}\PYG{o}{:} \PYG{n}{Reflexive} \PYG{n}{Basics}\PYG{o}{.}\PYG{n}{impl}
    \PYG{n}{eq\PYGZus{}Symmetric}\PYG{o}{:} \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{Symmetric} \PYG{n}{eq}
    \PYG{n}{eq\PYGZus{}Reflexive}\PYG{o}{:} \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{Reflexive} \PYG{n}{eq}
    \PYG{n}{Equivalence\PYGZus{}Symmetric}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{R} \PYG{o}{:} \PYG{n}{Relation\PYGZus{}Definitions}\PYG{o}{.}\PYG{n}{relation} \PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{,}
      \PYG{n}{Equivalence} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Symmetric} \PYG{n}{R}
    \PYG{n}{Equivalence\PYGZus{}Reflexive}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{R} \PYG{o}{:} \PYG{n}{Relation\PYGZus{}Definitions}\PYG{o}{.}\PYG{n}{relation} \PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{,}
      \PYG{n}{Equivalence} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Reflexive} \PYG{n}{R}
    \PYG{n}{PER\PYGZus{}Symmetric}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{R} \PYG{o}{:} \PYG{n}{Relation\PYGZus{}Definitions}\PYG{o}{.}\PYG{n}{relation} \PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{,}
      \PYG{n}{PER} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Symmetric} \PYG{n}{R}
    \PYG{n}{PreOrder\PYGZus{}Reflexive}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{R} \PYG{o}{:} \PYG{n}{Relation\PYGZus{}Definitions}\PYG{o}{.}\PYG{n}{relation} \PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{,}
      \PYG{n}{PreOrder} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Reflexive} \PYG{n}{R}
    \PYG{n}{reflexive\PYGZus{}eq\PYGZus{}dom\PYGZus{}reflexive}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{R\PYGZsq{}} \PYG{o}{:} \PYG{n}{Relation\PYGZus{}Definitions}\PYG{o}{.}\PYG{n}{relation} \PYG{n}{B}\PYG{o}{\PYGZcb{}}\PYG{o}{,}
      \PYG{n}{Reflexive} \PYG{n}{R\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Reflexive} \PYG{o}{(}\PYG{n}{eq} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{n}{R\PYGZsq{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{signature}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{SearchPattern (command)@\spxentry{SearchPattern}\spxextra{command}}

\begin{savenotes}\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{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{inside}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{outside}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Displays the name and type of all hypotheses of the
selected goal (if any) and theorems of the current context
ending with \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}},}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{P$_{\text{i}}$ \sphinxhyphen{}>}\DUrole{notation-sup}{*}} C}}} that match the pattern
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}}}.

\sphinxAtStartPar
See {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} for an explanation of the \sphinxcode{\sphinxupquote{inside}}/\sphinxcode{\sphinxupquote{outside}} clauses.

\begin{sphinxadmonition}{note}{Example: \sphinxstyleliteralintitle{\sphinxupquote{SearchPattern}} examples}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\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{n}{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{n}{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{n}{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{n}{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{n}{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{n}{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{n}{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{n}{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{n}{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{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{odd}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{odd}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{even}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{even}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{eqb}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{eqb}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{ltb}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{ltb}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}

\PYG{n}{SearchPattern} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{n}{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{n}{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{n}{list} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{List}\PYG{o}{.}\PYG{n}{lel} \PYG{n}{l} \PYG{n}{l}
\end{sphinxVerbatim}

\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{n}{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}

\end{fulllineitems}\end{savenotes}

\index{SearchRewrite (command)@\spxentry{SearchRewrite}\spxextra{command}}

\begin{savenotes}\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{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{inside}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{outside}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Displays the name and type of all hypotheses of the
selected goal (if any) and theorems of the current context that have the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}},}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{P$_{\text{i}}$ \sphinxhyphen{}>}\DUrole{notation-sup}{*}} LHS = RHS}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}}}
matches either \sphinxcode{\sphinxupquote{LHS}} or \sphinxcode{\sphinxupquote{RHS}}.

\sphinxAtStartPar
See {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} for an explanation of the \sphinxcode{\sphinxupquote{inside}}/\sphinxcode{\sphinxupquote{outside}} clauses.

\begin{sphinxadmonition}{note}{Example: \sphinxstyleliteralintitle{\sphinxupquote{SearchRewrite}} examples}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\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{n}{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{n}{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{n}{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{n}{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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{c0} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{|}\PYG{o}{|} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{b} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{Search Blacklist (table)@\spxentry{Search Blacklist}\spxextra{table}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:table.Search-Blacklist}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~Blacklist~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-table}]{\sphinxtermref{\DUrole{xref,std,std-term}{table}}}} 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.SearchPattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchPattern}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.SearchRewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchRewrite}}}}} queries.  A lemma whose
fully\sphinxhyphen{}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\_}}.

\sphinxAtStartPar
Use the {\hyperref[\detokenize{language/core/basic:coq:cmd.Add}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add}}}}} and {\hyperref[\detokenize{language/core/basic:coq:cmd.Remove}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove}}}}} commands to update the set of
blacklisted strings.

\end{fulllineitems}\end{savenotes}

\index{Search Output Name Only (flag)@\spxentry{Search Output Name Only}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} 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.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}\end{savenotes}



\subsubsection{Requests to the environment}
\label{\detokenize{proof-engine/vernacular-commands:requests-to-the-environment}}\label{\detokenize{proof-engine/vernacular-commands:id2}}\index{Print Assumptions (command)@\spxentry{Print Assumptions}\spxextra{command}}

\begin{savenotes}\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{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}
\sphinxAtStartPar
Displays all the assumptions (axioms, parameters and
variables) a theorem or definition depends on.

\sphinxAtStartPar
The message "Closed under the global context" indicates that the theorem or
definition has no dependencies.

\end{fulllineitems}\end{savenotes}

\index{Print Opaque Dependencies (command)@\spxentry{Print Opaque Dependencies}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Opaque-Dependencies}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Opaque~Dependencies~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}
\sphinxAtStartPar
Displays the assumptions and opaque constants that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} depends on.

\end{fulllineitems}\end{savenotes}

\index{Print Transparent Dependencies (command)@\spxentry{Print Transparent Dependencies}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Transparent-Dependencies}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Transparent~Dependencies~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}
\sphinxAtStartPar
Displays the assumptions and  transparent constants that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} depends on.

\end{fulllineitems}\end{savenotes}

\index{Print All Dependencies (command)@\spxentry{Print All Dependencies}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-All-Dependencies}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~All~Dependencies~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}
\sphinxAtStartPar
Displays all the assumptions and constants \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} depends on.

\end{fulllineitems}\end{savenotes}

\index{Locate (command)@\spxentry{Locate}\spxextra{command}}

\begin{savenotes}\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{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-reference}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Displays the full name of objects from Coq's various qualified namespaces
such as terms, modules and Ltac, thereby showing the module they are defined
in.  It also displays notation definitions.

\sphinxAtStartPar
Note that objects are reported only when the module containing them has
been loaded, such as through a {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} command.  Notation definitions
are reported only when the containing module has been imported
(e.g. with {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}} or {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}}).
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}] \leavevmode
\sphinxAtStartPar
refers to object names that end with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
refers to definitions of notations.  \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}
can be a single token in the notation such as "\sphinxcode{\sphinxupquote{\sphinxhyphen{}>}}" or a pattern that matches the
notation.  See {\hyperref[\detokenize{user-extensions/syntax-extensions:locating-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Locating notations}}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\% {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}}, if present, limits the reference to the scope bound to the delimiting
key \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}}}, such as, for example, \sphinxcode{\sphinxupquote{\DUrole{notation}{\%nat}}}.  (see Section
{\hyperref[\detokenize{user-extensions/syntax-extensions:localinterpretationrulesfornotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Local interpretation rules for notations}}}})

\end{description}

\end{fulllineitems}\end{savenotes}

\index{Locate Term (command)@\spxentry{Locate Term}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Locate-Term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~Term~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}
\sphinxAtStartPar
Like {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Locate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Locate}}}}}, but limits the search to terms

\end{fulllineitems}\end{savenotes}

\index{Locate Module (command)@\spxentry{Locate Module}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Locate-Module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~Module~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Like {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Locate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Locate}}}}}, but limits the search to modules

\end{fulllineitems}\end{savenotes}

\index{Locate Ltac (command)@\spxentry{Locate Ltac}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Locate-Ltac}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~Ltac~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Like {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Locate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Locate}}}}}, but limits the search to tactics

\end{fulllineitems}\end{savenotes}

\index{Locate Library (command)@\spxentry{Locate Library}\spxextra{command}}

\begin{savenotes}\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~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Displays the full name, status and file system path of the module \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, whether loaded or not.

\end{fulllineitems}\end{savenotes}

\index{Locate File (command)@\spxentry{Locate File}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
Displays the file system path of the file ending with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}.
Typically, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} has a suffix such as \sphinxcode{\sphinxupquote{.cmo}} or \sphinxcode{\sphinxupquote{.vo}} or \sphinxcode{\sphinxupquote{.v}} file, such as \sphinxcode{\sphinxupquote{\DUrole{notation}{Nat.v}}}.
\begin{quote}
\end{quote}

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example: Locate examples}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Locate} \PYG{n}{nat}\PYG{o}{.}
    \PYG{k+kn}{Inductive} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{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}


\subsubsection{Printing flags}
\label{\detokenize{proof-engine/vernacular-commands:printing-flags}}\label{\detokenize{proof-engine/vernacular-commands:id3}}\index{Fast Name Printing (flag)@\spxentry{Fast Name Printing}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.Fast-Name-Printing}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Fast~Name~Printing}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is turned on, Coq uses an asymptotically faster algorithm for the
generation of unambiguous names of bound variables while printing terms.
While faster, it is also less clever and results in a typically less elegant
display, e.g. it will generate more names rather than reusing certain names
across subterms. This flag is not enabled by default, because as Ltac
observes bound names, turning it on can break existing proof scripts.

\end{fulllineitems}\end{savenotes}



\subsubsection{Loading files}
\label{\detokenize{proof-engine/vernacular-commands:loading-files}}\label{\detokenize{proof-engine/vernacular-commands:id4}}
\sphinxAtStartPar
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 text files containing sequences of commands for Coq’s
toplevel. This kind of file is called a \sphinxstyleemphasis{script} for Coq. The standard
(and default) extension of Coq’s script files is .v.
\index{Load (command)@\spxentry{Load}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Load}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Load~\DUrole{repeat-wrapper}{\DUrole{repeat}{Verbose}\DUrole{notation-sup}{?}}~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}}}
\sphinxAtStartPar
Loads a file.  If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is specified, the command loads a file
named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.v}}}, searching successively in
each of the directories specified in the \sphinxstyleemphasis{loadpath}. (see Section
{\hyperref[\detokenize{language/core/modules:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}})

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} is specified, it must specify a complete filename.
\sphinxcode{\sphinxupquote{\textasciitilde{}}} and .. abbreviations are
allowed as well as shell variables. If no extension is specified, Coq
will use the default extension \sphinxcode{\sphinxupquote{.v}}.

\sphinxAtStartPar
Files loaded this way can't leave proofs open, nor can {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Load}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Load}}}}}
be used inside a proof.

\sphinxAtStartPar
We discourage the use of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Load}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Load}}}}}; use {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} instead.
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} loads \sphinxcode{\sphinxupquote{.vo}} files that were previously
compiled from \sphinxcode{\sphinxupquote{.v}} files.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Verbose}}} displays the Coq output for each command and tactic
in the loaded file, as if the commands and tactics were entered interactively.
\index{Can’t find file ‘ident’ on loadpath (error)@\spxentry{Can’t find file ‘ident’ on loadpath}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.Can_u2019t-find-file-_u2018ident_u2019-on-loadpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Can’t~find~file~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~on~loadpath.}}}}
\end{fulllineitems}\end{savenotes}

\index{Load is not supported inside proofs (error)@\spxentry{Load is not supported inside proofs}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{Files processed by Load cannot leave open proofs (error)@\spxentry{Files processed by Load cannot leave open proofs}\spxextra{error}}

\begin{savenotes}\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{savenotes}


\end{fulllineitems}\end{savenotes}



\subsubsection{Compiled files}
\label{\detokenize{proof-engine/vernacular-commands:compiled-files}}\label{\detokenize{proof-engine/vernacular-commands:id5}}
\sphinxAtStartPar
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 a module called a \sphinxstyleemphasis{library file}.
\index{Require (command)@\spxentry{Require}\spxextra{command}}\index{Require Import (command)@\spxentry{Require Import}\spxextra{command}}\index{Require Export (command)@\spxentry{Require Export}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}}\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Import}}\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Export}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Require~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{Import}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Export}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Loads compiled modules into the Coq environment.  For each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, which has the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{prefix}}$}}}} .}\DUrole{notation-sup}{*}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, the command searches for the logical name represented
by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{prefix}}$}}}}}}}s and loads the compiled file \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.vo}}} from the associated
filesystem directory.

\sphinxAtStartPar
The process is applied recursively to all the loaded files;
if they contain {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} commands, those commands are executed as well.
The compiled files must have been compiled with the same version of Coq.
The compiled files are neither replayed nor rechecked.
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Import}}} \sphinxhyphen{} additionally does an {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} on the loaded module, making components defined
in the module available by their short names

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Export}}} \sphinxhyphen{} additionally does an {\hyperref[\detokenize{language/core/modules:coq:cmd.Export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Export}}}}} on the loaded module, making components defined
in the module available by their short names \sphinxstyleemphasis{and} marking them to be exported by the current
module

\end{itemize}

\sphinxAtStartPar
If the required module has already been loaded, \sphinxcode{\sphinxupquote{\DUrole{notation}{Import}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{Export}}} make the command
equivalent to {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} or {\hyperref[\detokenize{language/core/modules:coq:cmd.Export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Export}}}}}.

\sphinxAtStartPar
The loadpath must contain the same mapping used to compile the file
(see Section {\hyperref[\detokenize{language/core/modules:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}). If
several files match, one of them is picked in an unspecified fashion.
Therefore, library authors should use a unique name for each module and
users are encouraged to use fully\sphinxhyphen{}qualified names
or the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{From … Require}}}}} command to load files.
\index{From … Require (command)@\spxentry{From … Require}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{From~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}~Require~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{Import}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Export}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Works like {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}}, but loads, for each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}},
the library whose fully\sphinxhyphen{}qualified name matches \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}.\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} .}\DUrole{notation-sup}{*}}{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
for some \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} .}\DUrole{notation-sup}{*}}}}}. This is useful to ensure that the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} library
comes from a particular package.

\end{fulllineitems}\end{savenotes}

\index{Cannot load ‘qualid’: no physical path bound to ‘dirpath’ (error)@\spxentry{Cannot load ‘qualid’: no physical path bound to ‘dirpath’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.Cannot-load-_u2018qualid_u2019:-no-physical-path-bound-to-_u2018dirpath_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~load~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}:~no~physical~path~bound~to~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{Cannot find library foo in loadpath (error)@\spxentry{Cannot find library foo in loadpath}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
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/core/modules:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}).

\end{fulllineitems}\end{savenotes}

\index{Compiled library ‘ident’.vo makes inconsistent assumptions over library ‘qualid’ (error)@\spxentry{Compiled library ‘ident’.vo makes inconsistent assumptions over library ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.Compiled-library-_u2018ident_u2019.vo-makes-inconsistent-assumptions-over-library-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Compiled~library~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.vo~makes~inconsistent~assumptions~over~library~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\sphinxAtStartPar
The command tried to load library file \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.vo that
depends on some specific version of library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} which is not the
one already loaded in the current Coq session. Probably \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.v}}} was
not properly recompiled with the last version of the file containing
module {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Bad magic number (error)@\spxentry{Bad magic number}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
The file \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.vo}}} was found but either it is not a
Coq compiled module, or it was compiled with an incompatible
version of Coq.

\end{fulllineitems}\end{savenotes}

\index{The file ‘ident’.vo contains library ‘qualid’ and not library ‘qualid’ (error)@\spxentry{The file ‘ident’.vo contains library ‘qualid’ and not library ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.The-file-_u2018ident_u2019.vo-contains-library-_u2018qualid_u2019-and-not-library-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~file~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.vo~contains~library~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{1}}$}}}}~and~not~library~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}}.}}}}
\sphinxAtStartPar
The library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}}}}} is indirectly required by a {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} or
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{From … Require}}}}} command.  The loadpath maps \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}}}}} to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.vo}}},
which was compiled using a loadpath that bound it to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{1}}$}}}}}}}.  Usually
the appropriate solution is to recompile \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.v}}} using the correct loadpath.
See {\hyperref[\detokenize{language/core/modules:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}.

\end{fulllineitems}\end{savenotes}

\index{Require inside a module is deprecated and strongly discouraged. You can Require a module at toplevel and optionally Import it inside another one (warning)@\spxentry{Require inside a module is deprecated and strongly discouraged. You can Require a module at toplevel and optionally Import it inside another one}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:warn.Require-inside-a-module-is-deprecated-and-strongly-discouraged.-You-can-Require-a-module-at-toplevel-and-optionally-Import-it-inside-another-one}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Require~inside~a~module~is~deprecated~and~strongly~discouraged.~You~can~Require~a~module~at~toplevel~and~optionally~Import~it~inside~another~one.}}}}
\sphinxAtStartPar
Note that the {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} and {\hyperref[\detokenize{language/core/modules:coq:cmd.Export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Export}}}}} commands can be used inside modules.


\sphinxstrong{See also:}
\nopagebreak


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



\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Print Libraries (command)@\spxentry{Print Libraries}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This command displays the list of library files loaded in the
current Coq session.

\end{fulllineitems}\end{savenotes}

\index{Declare ML Module (command)@\spxentry{Declare ML Module}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This commands dynamically loads OCaml compiled code from
a \sphinxcode{\sphinxupquote{\DUrole{notation}{.mllib}}} file.
It is used to load plugins dynamically.  The
files must be accessible in the current OCaml loadpath (see
{\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{command line option}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}I}}} and command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Add-ML-Path}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add ML Path}}}}}).  The
\sphinxcode{\sphinxupquote{\DUrole{notation}{.mllib}}} suffix may be omitted.

\sphinxAtStartPar
This command is reserved for plugin developers, who should provide
a .v file containing the command. Users of the plugins will then generally
load the .v file.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute.  If present,
the listed files are not exported, even if they're outside a section.
\index{File not found on loadpath: ‘string’ (error)@\spxentry{File not found on loadpath: ‘string’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.File-not-found-on-loadpath:-_u2018string_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{File~not~found~on~loadpath:~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Print ML Modules (command)@\spxentry{Print ML Modules}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This prints the name of all OCaml modules loaded with {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Declare-ML-Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare ML Module}}}}}.
To know from where these module were loaded, the user
should use the command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Locate-File}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Locate File}}}}}.

\end{fulllineitems}\end{savenotes}



\subsubsection{Loadpath}
\label{\detokenize{proof-engine/vernacular-commands:loadpath}}\label{\detokenize{proof-engine/vernacular-commands:id6}}
\sphinxAtStartPar
Loadpaths are preferably managed using Coq command line options (see
Section {\hyperref[\detokenize{language/core/modules:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}), but there are also commands
to manage them within Coq. These commands are only meant to be issued in
the toplevel, and using them in source files is discouraged.
\index{Pwd (command)@\spxentry{Pwd}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Pwd}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Pwd}}}}
\sphinxAtStartPar
This command displays the current working directory.

\end{fulllineitems}\end{savenotes}

\index{Cd (command)@\spxentry{Cd}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Cd}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cd~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} is specified, changes the current directory according to {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} which
can be any valid path.  Otherwise, it displays the current directory.

\end{fulllineitems}\end{savenotes}

\index{Add LoadPath (command)@\spxentry{Add LoadPath}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~as~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} .}\DUrole{notation-sup}{*}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
This command is equivalent to the command line option
\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}Q {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}}. It adds a mapping to the loadpath from
the logical name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}} to the file system directory \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}.
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}} is a prefix of a module name.  The module name hierarchy
follows the file system hierarchy.  On Linux, for example, the prefix
\sphinxcode{\sphinxupquote{A.B.C}} maps to the directory \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}/B/C}}}.  Avoid using spaces after a \sphinxcode{\sphinxupquote{.}} in the
path because the parser will interpret that as the end of a command or tactic.

\end{itemize}

\end{fulllineitems}\end{savenotes}

\index{Add Rec LoadPath (command)@\spxentry{Add Rec LoadPath}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~as~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}}}
\sphinxAtStartPar
This command is equivalent to the command line option
\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}R {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}}. It adds the physical directory string and all its
subdirectories to the current Coq loadpath.

\end{fulllineitems}\end{savenotes}

\index{Remove LoadPath (command)@\spxentry{Remove LoadPath}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
This command removes the path \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} from the current Coq loadpath.

\end{fulllineitems}\end{savenotes}

\index{Print LoadPath (command)@\spxentry{Print LoadPath}\spxextra{command}}

\begin{savenotes}\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~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This command displays the current Coq loadpath.  If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}} is specified,
displays only the paths that extend that prefix.

\end{fulllineitems}\end{savenotes}

\index{Add ML Path (command)@\spxentry{Add ML Path}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
Equivalent to the {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{command line option}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}I {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}.  Adds the path \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} to the current OCaml
loadpath (cf. {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Declare-ML-Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare ML Module}}}}}). It is for
convenience, such as for use in an interactive session, and it
is not exported to compiled files. For separation of concerns with
respect to the relocability of files, we recommend using
\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}I {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Print ML Path (command)@\spxentry{Print ML Path}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Displays the current OCaml loadpath, as provided by
the {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{command line option}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}I {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} or by the command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Add-ML-Path}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add
ML Path}}}}} \sphinxcode{\sphinxupquote{@string}} (cf. {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Declare-ML-Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare ML Module}}}}}).

\end{fulllineitems}\end{savenotes}



\subsubsection{Backtracking}
\label{\detokenize{proof-engine/vernacular-commands:backtracking}}\label{\detokenize{proof-engine/vernacular-commands:backtracking-subsection}}
\sphinxAtStartPar
The backtracking commands described in this section can only be used
interactively, they cannot be part of a Coq file loaded via
\sphinxcode{\sphinxupquote{Load}} or compiled by \sphinxcode{\sphinxupquote{coqc}}.
\index{Reset (command)@\spxentry{Reset}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This command removes all the objects in the environment since \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
was introduced, including \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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 (error)@\spxentry{‘ident’: no such entry}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn._u2018ident_u2019:-no-such-entry}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:~no~such~entry.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Reset Initial (command)@\spxentry{Reset Initial}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Reset-Initial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reset~Initial}}}}
\sphinxAtStartPar
Goes back to the initial state, just after the start
of the interactive session.

\end{fulllineitems}\end{savenotes}

\index{Back (command)@\spxentry{Back}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Back}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Back~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Undoes all the effects of the last \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}s.  If
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} is not specified, the command undoes one sentence.
Sentences read from a \sphinxcode{\sphinxupquote{.v}} file via a {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Load}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Load}}}}} are considered a
single sentence.  While {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Back}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Back}}}}} can undo tactics and commands executed
within proof mode, once you exit proof mode, such as with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}, all
the statements executed within are thereafter considered a single sentence.
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Back}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Back}}}}} immediately following {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} gets you back to the state
just after the statement of the proof.
\index{Invalid backtrack (error)@\spxentry{Invalid backtrack}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
The user wants to undo more commands than available in the history.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{BackTo (command)@\spxentry{BackTo}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This command brings back the system to the state labeled \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}},
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 \sphinxhyphen{}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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}′ ≤ {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} if
necessary.

\end{fulllineitems}\end{savenotes}



\subsubsection{Quitting and debugging}
\label{\detokenize{proof-engine/vernacular-commands:quitting-and-debugging}}\label{\detokenize{proof-engine/vernacular-commands:id7}}\index{Quit (command)@\spxentry{Quit}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Quit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Quit}}}}
\sphinxAtStartPar
Causes Coq to exit.  Valid only in coqtop.

\end{fulllineitems}\end{savenotes}

\index{Drop (command)@\spxentry{Drop}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Drop}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Drop}}}}
\sphinxAtStartPar
This command temporarily enters the OCaml toplevel.
It is a debug facility used by Coq’s implementers.  Valid only in the
bytecode version of coqtop.
The OCaml command:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZsh{}use \PYGZdq{}include\PYGZdq{};;
\end{sphinxVerbatim}

\sphinxAtStartPar
adds the right loadpaths and loads some toplevel printers for all
abstract types of Coq\sphinxhyphen{} section\_path, identifiers, terms, judgments, ….
You can also use the file base\_include instead, that loads only the
pretty\sphinxhyphen{}printers for section\_paths and identifiers. You can return back
to Coq with the command:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
go();;
\end{sphinxVerbatim}

\begin{sphinxadmonition}{warning}{Warning:}\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
It only works with the bytecode version of Coq (i.e. \sphinxcode{\sphinxupquote{coqtop.byte}},
see Section \sphinxcode{\sphinxupquote{interactive\sphinxhyphen{}use}}).

\item {} 
\sphinxAtStartPar
You must have compiled Coq from the source package and set the
environment variable COQTOP to the root of your copy of the sources
(see Section \sphinxcode{\sphinxupquote{customization\sphinxhyphen{}by\sphinxhyphen{}environment\sphinxhyphen{}variables}}).

\end{enumerate}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{Time (command)@\spxentry{Time}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Time}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Time~{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}}
\sphinxAtStartPar
Executes \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}} and displays the
time needed to execute it.

\end{fulllineitems}\end{savenotes}

\index{Redirect (command)@\spxentry{Redirect}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}}
\sphinxAtStartPar
Executes \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}, redirecting its
output to the file "\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}.out".

\end{fulllineitems}\end{savenotes}

\index{Timeout (command)@\spxentry{Timeout}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}}
\sphinxAtStartPar
Executes \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}. If the operation
has not terminated after \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} seconds, then it is interrupted and an error message is
displayed.
\index{Default Timeout (option)@\spxentry{Default Timeout}\spxextra{option}}

\begin{savenotes}\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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} is set, each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}} is treated
as if it was prefixed with {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Timeout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Timeout}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}, except
for {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Timeout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Timeout}}}}} commands themselves.  If unset, no timeout is
applied.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Fail (command)@\spxentry{Fail}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Fail}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Fail~{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}}
\sphinxAtStartPar
For debugging scripts, sometimes it is desirable to know whether a
command or a tactic fails. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}} fails, then
\sphinxcode{\sphinxupquote{\DUrole{notation}{Fail {\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}} succeeds (except for
critical errors, such as "stack overflow"), without changing the
proof state.  In interactive mode, the system prints a message
confirming the failure.
\index{The command has not failed"! (error)@\spxentry{The command has not failed"!}\spxextra{error}}

\begin{savenotes}\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!}}}}
\sphinxAtStartPar
If the given \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-command}]{\sphinxcrossref{\DUrole{hole}{command}}}}}}} succeeds, then \sphinxcode{\sphinxupquote{\DUrole{notation}{Fail {\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}}
fails with this error message.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Time}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Time}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Redirect}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Redirect}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Timeout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Timeout}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fail}}}}} are
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-control_command}}\sphinxcode{\sphinxupquote{control\_command}}}s. For these commands, attributes and goal
selectors, when specified, are part of the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-sentence}]{\sphinxcrossref{\DUrole{hole}{sentence}}}}}}} argument, and thus come after
the control command prefix and before the inner command or tactic. For
example: \sphinxcode{\sphinxupquote{Time \#{[} local {]} Definition foo := 0.}} or \sphinxcode{\sphinxupquote{Fail Timeout 10 all: auto.}}
\end{sphinxadmonition}


\subsubsection{Controlling display}
\label{\detokenize{proof-engine/vernacular-commands:controlling-display}}\label{\detokenize{proof-engine/vernacular-commands:id8}}\index{Silent (flag)@\spxentry{Silent}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.Silent}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Silent}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls the normal displaying.

\end{fulllineitems}\end{savenotes}

\index{Warnings (option)@\spxentry{Warnings}\spxextra{option}}

\begin{savenotes}\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-with-sub}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{+}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}"}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} configures the display of warnings. It is experimental, and
expects, between quotes, a comma\sphinxhyphen{}separated list of warning names or
categories. Adding \sphinxhyphen{} 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 \sphinxcode{\sphinxupquote{A,\sphinxhyphen{}A}} is equivalent to \sphinxcode{\sphinxupquote{\sphinxhyphen{}A}}.

\end{fulllineitems}\end{savenotes}

\index{Debug (option)@\spxentry{Debug}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:opt.Debug}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~"\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}"}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} configures the display of debug messages. Each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} enables debug messages
for that component, while  \sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} disables messages for the component.
\sphinxcode{\sphinxupquote{all}} activates or deactivates all other components.  \sphinxcode{\sphinxupquote{backtrace}} controls printing of
error backtraces.

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:coq:cmd.Test}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Test}}}}} \sphinxcode{\sphinxupquote{Debug}} displays the list of components and their enabled/disabled state.

\end{fulllineitems}\end{savenotes}

\index{Printing Width (option)@\spxentry{Printing Width}\spxextra{option}}

\begin{savenotes}\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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} sets which left\sphinxhyphen{}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}\end{savenotes}

\index{Printing Depth (option)@\spxentry{Printing Depth}\spxextra{option}}

\begin{savenotes}\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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} controls the nesting depth of the formatter used for pretty\sphinxhyphen{}
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}\end{savenotes}

\index{Printing Compact Contexts (flag)@\spxentry{Printing Compact Contexts}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} 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}\end{savenotes}

\index{Printing Unfocused (flag)@\spxentry{Printing Unfocused}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls whether unfocused goals are displayed. Such goals are
created by focusing other goals with bullets (see {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:bullets}]{\sphinxcrossref{\DUrole{std,std-ref}{Bullets}}}} or
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:curly-braces}]{\sphinxcrossref{\DUrole{std,std-ref}{curly braces}}}}). It is off by default.

\end{fulllineitems}\end{savenotes}

\index{Printing Dependent Evars Line (flag)@\spxentry{Printing Dependent Evars Line}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls the printing of the “(dependent evars: …)” information
after each tactic.  The information is used by the Prooftree tool in Proof
General. (\sphinxurl{https://askra.de/software/prooftree})

\end{fulllineitems}\end{savenotes}



\subsubsection{Printing constructions in full}
\label{\detokenize{proof-engine/vernacular-commands:printing-constructions-in-full}}\label{\detokenize{proof-engine/vernacular-commands:printing-constructions-full}}\index{Printing All (flag)@\spxentry{Printing All}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~All}}}}
\sphinxAtStartPar
Coercions, implicit arguments, the type of pattern matching, but also
notations (see {\hyperref[\detokenize{user-extensions/syntax-extensions:syntax-extensions-and-notation-scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax extensions and notation scopes}}}}) can obfuscate the behavior of some
tactics (typically the tactics applying to occurrences of subterms are
sensitive to the implicit arguments). Turning this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} on
deactivates all high\sphinxhyphen{}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{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} includes the effects of the flags
{\hyperref[\detokenize{language/extensions/implicit-arguments: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/extensions/match:coq:flag.Printing-Synth}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Synth}}}}},
{\hyperref[\detokenize{language/core/records: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\sphinxhyphen{}level printing features, use the command \sphinxcode{\sphinxupquote{Unset Printing All}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
In some cases, setting {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} may display terms
that are so big they become very hard to read.  One technique to work around
this is use {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Undelimit-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Undelimit Scope}}}}} and/or {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Close-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Close Scope}}}}} to turn off the
printing of notations bound to particular scope(s).  This can be useful when
notations in a given scope are getting in the way of understanding
a goal, but turning off all notations with {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} would make
the goal unreadable.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\subsubsection{Controlling Typing Flags}
\label{\detokenize{proof-engine/vernacular-commands:controlling-typing-flags}}\label{\detokenize{proof-engine/vernacular-commands:id9}}\index{Guard Checking (flag)@\spxentry{Guard Checking}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.Guard-Checking}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Guard~Checking}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} can be used to enable/disable the guard checking of
fixpoints. Warning: this can break the consistency of the system, use at your
own risk. Decreasing argument can still be specified: the decrease is not checked
anymore but it still affects the reduction of the term. Unchecked fixpoints are
printed by {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Assumptions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Assumptions}}}}}.

\end{fulllineitems}\end{savenotes}

\index{bypass\_check(guard) (attribute)@\spxentry{bypass\_check(guard)}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(guard)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{bypass\_check(guard\DUrole{repeat-wrapper}{\DUrole{repeat}{=~\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}})}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{boolean attribute}}}} is similar to the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Guard-Checking}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Guard Checking}}}}} flag, but on a per\sphinxhyphen{}declaration
basis. Disable guard checking locally with \sphinxcode{\sphinxupquote{bypass\_check(guard)}}.

\end{fulllineitems}\end{savenotes}

\index{Positivity Checking (flag)@\spxentry{Positivity Checking}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.Positivity-Checking}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Positivity~Checking}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} can be used to enable/disable the positivity checking of inductive
types and the productivity checking of coinductive types. Warning: this can
break the consistency of the system, use at your own risk. Unchecked
(co)inductive types are printed by {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Assumptions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Assumptions}}}}}.

\end{fulllineitems}\end{savenotes}

\index{bypass\_check(positivity) (attribute)@\spxentry{bypass\_check(positivity)}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(positivity)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{bypass\_check(positivity\DUrole{repeat-wrapper}{\DUrole{repeat}{=~\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}})}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{boolean attribute}}}} is similar to the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Positivity-Checking}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Positivity Checking}}}}} flag, but on a per\sphinxhyphen{}declaration basis.
Disable positivity checking locally with \sphinxcode{\sphinxupquote{bypass\_check(positivity)}}.

\end{fulllineitems}\end{savenotes}

\index{Universe Checking (flag)@\spxentry{Universe Checking}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.Universe-Checking}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~Checking}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} can be used to enable/disable the checking of universes, providing a
form of "type in type".  Warning: this breaks the consistency of the system, use
at your own risk.  Constants relying on "type in type" are printed by
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Assumptions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Assumptions}}}}}. It has the same effect as \sphinxcode{\sphinxupquote{\sphinxhyphen{}type\sphinxhyphen{}in\sphinxhyphen{}type}} command line
argument (see {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{By command line options}}}}).

\end{fulllineitems}\end{savenotes}

\index{bypass\_check(universes) (attribute)@\spxentry{bypass\_check(universes)}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:attr.bypass_check(universes)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{bypass\_check(universes\DUrole{repeat-wrapper}{\DUrole{repeat}{=~\DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}})}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{boolean attribute}}}} is similar to the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Universe-Checking}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Checking}}}}} flag, but on a per\sphinxhyphen{}declaration basis.
Disable universe checking locally with \sphinxcode{\sphinxupquote{bypass\_check(universes)}}.

\end{fulllineitems}\end{savenotes}

\index{Print Typing Flags (command)@\spxentry{Print Typing Flags}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Typing-Flags}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Typing~Flags}}}}
\sphinxAtStartPar
Print the status of the three typing flags: guard checking, positivity checking
and universe checking.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
See also {\hyperref[\detokenize{addendum/sprop:coq:flag.Cumulative-StrictProp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Cumulative StrictProp}}}}} in the \(\SProp\) chapter.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Unset} \PYG{n}{Guard} \PYG{n}{Checking}\PYG{o}{.}

\PYG{k+kn}{Print} \PYG{n}{Typing} \PYG{n}{Flags}\PYG{o}{.}
    \PYG{n}{check\PYGZus{}guarded}\PYG{o}{:} \PYG{n+nb+bp}{false}
    \PYG{n}{check\PYGZus{}positive}\PYG{o}{:} \PYG{n+nb+bp}{true}
    \PYG{n}{check\PYGZus{}universes}\PYG{o}{:} \PYG{n+nb+bp}{true}
    \PYG{n}{cumulative} \PYG{n}{sprop}\PYG{o}{:} \PYG{n+nb+bp}{false}
    \PYG{n}{definitional} \PYG{n}{uip}\PYG{o}{:} \PYG{n+nb+bp}{false}


\PYG{k+kn}{Fixpoint} \PYG{n}{f} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{False}
  \PYG{o}{:=} \PYG{n}{f} \PYG{n}{n}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}


\PYG{k+kn}{Fixpoint} \PYG{n}{ackermann} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{n}
  \PYG{o}{|} \PYG{n}{S} \PYG{n}{m} \PYG{o}{=\PYGZgt{}}
    \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
    \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{ackermann} \PYG{n}{m} \PYG{l+m+mi}{1}
    \PYG{o}{|} \PYG{n}{S} \PYG{n}{n} \PYG{o}{=\PYGZgt{}} \PYG{n}{ackermann} \PYG{n}{m} \PYG{o}{(}\PYG{n}{ackermann} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)} \PYG{n}{n}\PYG{o}{)}
    \PYG{k}{end}
  \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{ackermann} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{ackermann} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}


\PYG{k+kn}{Print} \PYG{n}{Assumptions} \PYG{n}{ackermann}\PYG{o}{.}
    \PYG{n}{Axioms}\PYG{o}{:}
    \PYG{n}{ackermann} \PYG{k}{is} \PYG{n}{assumed} \PYG{n}{to} \PYG{n}{be} \PYG{n}{guarded}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that the proper way to define the Ackermann function is to use
an inner fixpoint:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{ack} \PYG{n}{m} \PYG{o}{:=}
  \PYG{k}{fix} \PYG{n}{ackm} \PYG{n}{n} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{n}
  \PYG{o}{|} \PYG{n}{S} \PYG{n}{m\PYGZsq{}} \PYG{o}{=\PYGZgt{}}
    \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
    \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{ack} \PYG{n}{m\PYGZsq{}} \PYG{l+m+mi}{1}
    \PYG{o}{|} \PYG{n}{S} \PYG{n}{n\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{ack} \PYG{n}{m\PYGZsq{}} \PYG{o}{(}\PYG{n}{ackm} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}
    \PYG{k}{end}
  \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{ack} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{ack} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Typing flags may not be changed while inside sections.


\subsubsection{Internal registration commands}
\label{\detokenize{proof-engine/vernacular-commands:internal-registration-commands}}\label{\detokenize{proof-engine/vernacular-commands:id10}}
\sphinxAtStartPar
Due to their internal nature, the commands that are presented in this section
are not for general use. They are meant to appear only in standard libraries and
in support libraries of plug\sphinxhyphen{}ins.


\paragraph{Exposing constants to OCaml libraries}
\label{\detokenize{proof-engine/vernacular-commands:exposing-constants-to-ocaml-libraries}}\label{\detokenize{proof-engine/vernacular-commands:id11}}\index{Register (command)@\spxentry{Register}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Register}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Register~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{1}}$}}}}~as~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}}}}}}
\sphinxAtStartPar
Makes the constant \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{1}}$}}}}}}} accessible to OCaml libraries under
the name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}}}}}.  The constant can then be dynamically located
in OCaml code by
calling \sphinxcode{\sphinxupquote{\DUrole{notation}{Coqlib.lib\_ref "{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}}"}}}.  The OCaml code doesn't need
to know where the constant is defined (what file, module, library, etc.).

\sphinxAtStartPar
As a special case, when the first segment of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}}}}} is \sphinxcode{\sphinxupquote{\DUrole{name}{kernel}}},
the constant is exposed to the kernel. For instance, the \sphinxcode{\sphinxupquote{PrimInt63}} module
features the following declaration:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Register} \PYG{n}{bool} \PYG{k}{as} \PYG{n}{kernel}\PYG{o}{.}\PYG{n}{ind\PYGZus{}bool}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This makes the kernel aware of the \sphinxcode{\sphinxupquote{bool}} type, which is used, for example,
to define the return type of the \sphinxcode{\sphinxupquote{\DUrole{operator}{\#}\DUrole{name}{int63\_eq}}} primitive.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{language/core/primitive:primitive-integers}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Integers}}}}



\end{fulllineitems}\end{savenotes}



\paragraph{Inlining hints for the fast reduction machines}
\label{\detokenize{proof-engine/vernacular-commands:inlining-hints-for-the-fast-reduction-machines}}\index{Register Inline (command)@\spxentry{Register Inline}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Register-Inline}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Register~Inline~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Gives a hint to the reduction machines (VM and native) that
the body of the constant \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} should be inlined in the generated code.

\end{fulllineitems}\end{savenotes}



\paragraph{Registering primitive operations}
\label{\detokenize{proof-engine/vernacular-commands:registering-primitive-operations}}\index{Primitive (command)@\spxentry{Primitive}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.Primitive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Primitive~{\hyperref[\detokenize{language/core/assumptions:grammar-token-ident_decl}]{\sphinxcrossref{\DUrole{hole}{ident\_decl}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~:=~\#{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Makes the primitive type or primitive operator \sphinxcode{\sphinxupquote{\DUrole{notation}{\#{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} defined in OCaml
accessible in Coq commands and tactics.
For internal use by implementors of Coq's standard library or standard library
replacements.  No space is allowed after the \sphinxcode{\sphinxupquote{\#}}.  Invalid values give a syntax
error.

\sphinxAtStartPar
For example, the standard library files \sphinxcode{\sphinxupquote{PrimInt63.v}} and \sphinxcode{\sphinxupquote{PrimFloat.v}} use {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Primitive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Primitive}}}}}
to support, respectively, the features described in {\hyperref[\detokenize{language/core/primitive:primitive-integers}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Integers}}}} and
{\hyperref[\detokenize{language/core/primitive:primitive-floats}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Floats}}}}.

\sphinxAtStartPar
The types associated with an operator must be declared to the kernel before declaring operations
that use the type.  Do this with {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Primitive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Primitive}}}}} for primitive types and
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Register}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Register}}}}} with the \sphinxcode{\sphinxupquote{\DUrole{name}{kernel}}} prefix for other types.  For example,
in \sphinxcode{\sphinxupquote{PrimInt63.v}}, \sphinxcode{\sphinxupquote{\#int63\_type}} must be declared before the associated operations.
\index{The type ‘ident’ must be registered before this construction can be typechecked (error)@\spxentry{The type ‘ident’ must be registered before this construction can be typechecked}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.The-type-_u2018ident_u2019-must-be-registered-before-this-construction-can-be-typechecked}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~type~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~must~be~registered~before~this~construction~can~be~typechecked.}}}}
\sphinxAtStartPar
The type must be defined with {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Primitive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Primitive}}}}} command before this
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Primitive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Primitive}}}}} command (declaring an operation using the type) will succeed.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\chapter{Proofs}
\label{\detokenize{index:proofs}}

\section{Basic proof writing}
\label{\detokenize{proofs/writing-proofs/index:basic-proof-writing}}\label{\detokenize{proofs/writing-proofs/index:writing-proofs}}\label{\detokenize{proofs/writing-proofs/index::doc}}
\sphinxAtStartPar
Coq is an interactive theorem prover, or proof assistant, which means
that proofs can be constructed interactively through a dialog between
the user and the assistant.  The building blocks for this dialog are
tactics which the user will use to represent steps in the proof of a
theorem.

\sphinxAtStartPar
The first section presents the proof mode (the core mechanism of the
dialog between the user and the proof assistant).  Then, several
sections describe the available tactics.  The last section covers the
SSReflect proof language, which provides a consistent alternative set
of tactics to the standard basic tactics.

\sphinxAtStartPar
Additional tactics are documented in the next chapter
{\hyperref[\detokenize{proofs/automatic-tactics/index:automatic-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Automatic solvers and programmable tactics}}}}.


\subsection{Proof mode}
\label{\detokenize{proofs/writing-proofs/proof-mode:proof-mode}}\label{\detokenize{proofs/writing-proofs/proof-mode:proofhandling}}\label{\detokenize{proofs/writing-proofs/proof-mode::doc}}
\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-proof-mode}}Proof mode} is used to prove theorems.
Coq enters proof mode when you begin a proof,
such as with the {\hyperref[\detokenize{language/core/definitions:coq:cmd.Theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} command.  It exits proof mode when
you complete a proof, such as with the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} command.  Tactics,
which are available only in proof mode, incrementally transform incomplete
proofs to eventually generate a complete proof.

\sphinxAtStartPar
When you run Coq interactively, such as through CoqIDE, Proof General or
coqtop, Coq shows the current proof state (the incomplete proof) as you
enter tactics.  This information isn't shown when you run Coq in batch
mode with \sphinxcode{\sphinxupquote{coqc}}.


\subsubsection{Proof State}
\label{\detokenize{proofs/writing-proofs/proof-mode:proof-state}}
\sphinxAtStartPar
The \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-proof-state}}proof state} consists of one or more unproven goals.
Each goal has a \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-conclusion}}conclusion} (the statement that is to be proven)
and a \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-local-context}}local context}, which contains named {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-hypothesis}]{\sphinxtermref{\DUrole{xref,std,std-term}{hypotheses}}}}
(which are propositions), variables and local definitions that can be used in
proving the conclusion.  The proof may also use \sphinxstyleemphasis{constants} from the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-global-environment}]{\sphinxtermref{\DUrole{xref,std,std-term}{global environment}}}}
such as definitions and proven theorems.

\sphinxAtStartPar
The term "\DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-goal}}goal}" may refer to an entire goal or to the conclusion
of a goal, depending on the context.

\sphinxAtStartPar
The conclusion appears below a line and the local context appears above the line.
The conclusion is a type.  Each item in the local context begins with a name
and ends, after a colon, with an associated type.
Local definitions are shown in the form \sphinxcode{\sphinxupquote{n := 0 : nat}}, for example, in which \sphinxcode{\sphinxupquote{nat}} is the
type of \sphinxcode{\sphinxupquote{0}}.

\sphinxAtStartPar
The local context of a goal contains items specific to the goal as well
as section\sphinxhyphen{}local variables and hypotheses (see {\hyperref[\detokenize{language/core/assumptions:gallina-assumptions}]{\sphinxcrossref{\DUrole{std,std-ref}{Assumptions}}}}) defined
in the current {\hyperref[\detokenize{language/core/sections:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{section}}}}.  The latter are included in the
initial proof state.
Items in the local context are ordered; an item can only refer to items that appear
before it.  (A more mathematical description of the \sphinxstyleemphasis{local context} is
{\hyperref[\detokenize{language/cic:local-context}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.)

\sphinxAtStartPar
The \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-global-environment}}global environment} has definitions and proven theorems that are global in scope.
(A more mathematical description of the \sphinxstyleemphasis{global environment} is {\hyperref[\detokenize{language/cic:global-environment}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.)

\sphinxAtStartPar
When you begin proving a theorem, the proof state shows
the statement of the theorem below the line and often nothing in the
local context:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}

\sphinxAtStartPar
After applying the {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}} {\hyperref[\detokenize{language/core/basic:term-tactic}]{\sphinxtermref{\DUrole{xref,std,std-term}{tactic}}}}, we see hypotheses above the line.
The names of variables (\sphinxcode{\sphinxupquote{n}} and \sphinxcode{\sphinxupquote{m}}) and hypotheses (\sphinxcode{\sphinxupquote{H}}) appear before a colon, followed by
the type they represent.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \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{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}

\sphinxAtStartPar
Some tactics, such as {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.split}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{split}}}}}, create new goals, which may
be referred to as \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-subgoal}}subgoals} for clarity.
Goals are numbered from 1 to N at each step of the proof to permit applying a
tactic to specific goals.  The local context is only shown for the first goal.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \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{l+m+mi}{1}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}

\sphinxAtStartPar
"Variables" may refer specifically to local context items for which the type of their type
is \sphinxcode{\sphinxupquote{Set}} or \sphinxcode{\sphinxupquote{Type}}, and \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-hypothesis}}"hypotheses"} refers to items that are
{\hyperref[\detokenize{language/core/sorts:term-proposition}]{\sphinxtermref{\DUrole{xref,std,std-term}{propositions}}}},
for which the type of their type is \sphinxcode{\sphinxupquote{Prop}} or \sphinxcode{\sphinxupquote{SProp}},
but these terms are also used interchangeably.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{n}{type} \PYG{k}{of} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}
    \PYG{n}{type} \PYG{k}{of} \PYG{n}{nat} \PYG{o}{:} \PYG{k+kn}{Set}

    \PYG{n}{type} \PYG{k}{of} \PYG{n}{H} \PYG{o}{:} \PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{n}{m}\PYG{o}{)}
    \PYG{n}{type} \PYG{k}{of} \PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{n}{m}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

\sphinxAtStartPar
A proof script, consisting of the tactics that are applied to prove a
theorem, is often informally referred to as a "proof".
The real proof, whether complete or incomplete, is a term, the \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-proof-term}}proof term},
which users may occasionally want to examine.  (This is based on the
\sphinxstyleemphasis{Curry\sphinxhyphen{}Howard isomorphism} {[}\hyperlink{cite.zebibliography:id3}{Bar81}, \hyperlink{cite.zebibliography:id26}{GLT89}, \hyperlink{cite.zebibliography:id27}{How80}, \hyperlink{cite.zebibliography:id29}{Hue89}{]}, which is
a correspondence between between proofs and terms and between
propositions and types of λ\sphinxhyphen{}calculus.  The isomorphism is also
sometimes called the "propositions\sphinxhyphen{}as\sphinxhyphen{}types correspondence".)

\sphinxAtStartPar
The {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Proof}}}}} command displays the incomplete proof term
before you've completed the proof.  For example, here's the proof
term after using the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.split}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{split}}}}} tactic above:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show} \PYG{k+kn}{Proof}\PYG{o}{.}
    \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{conj} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{?}\PYG{n}{Goal0}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
The incomplete parts, the goals, are represented by
{\hyperref[\detokenize{language/extensions/evars:term-existential-variable}]{\sphinxtermref{\DUrole{xref,std,std-term}{existential variables}}}}
with names that begin with \sphinxcode{\sphinxupquote{?Goal}}.  The {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Existentials}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Existentials}}}}} command
shows each existential with the hypotheses and conclusion for the associated goal.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show} \PYG{n}{Existentials}\PYG{o}{.}
    \PYG{n}{Existential} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{:} \PYG{o}{[}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}  \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}  \PYG{n}{H} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{n}{m} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{n}{P} \PYG{l+m+mi}{1}\PYG{o}{]}
    \PYG{n}{Existential} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{o}{?}\PYG{n}{Goal0} \PYG{o}{:} \PYG{o}{[}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}  \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}  \PYG{n}{H} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{n}{m} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{n}{P} \PYG{l+m+mi}{2}\PYG{o}{]}
\end{sphinxVerbatim}

\sphinxAtStartPar
Coq's kernel verifies the correctness of proof terms when it exits
proof mode by checking that the proof term is {\hyperref[\detokenize{language/core/basic:term-well-typed}]{\sphinxtermref{\DUrole{xref,std,std-term}{well\sphinxhyphen{}typed}}}} and
that its type is the same as the theorem statement.

\sphinxAtStartPar
After a proof is completed, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Print}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print}}}}} \sphinxcode{\sphinxupquote{<theorem\_name>}}
shows the proof term and its type.  The type appears after
the colon (\sphinxcode{\sphinxupquote{forall ...}}), as for this theorem from Coq's standard library:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{proj1}\PYG{o}{.}
    \PYG{n}{Fetching} \PYG{n}{opaque} \PYG{n}{proofs} \PYG{n}{from} \PYG{n}{disk} \PYG{k}{for} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Logic}
    \PYG{n}{proj1} \PYG{o}{=} 
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
    \PYG{k}{match} \PYG{n}{H} \PYG{k}{with}
    \PYG{o}{|} \PYG{n}{conj} \PYG{n}{x} \PYG{n}{x0} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{H0} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{B}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{H0}\PYG{o}{)} \PYG{n}{x} \PYG{n}{x0}
    \PYG{k}{end}
         \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{k+kn}{Arguments} \PYG{n}{proj1} \PYG{o}{[}\PYG{n}{A} \PYG{n}{B}\PYG{o}{]}\PYG{o}{\PYGZpc{}}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}
\end{sphinxVerbatim}


\subsubsection{Entering and exiting proof mode}
\label{\detokenize{proofs/writing-proofs/proof-mode:entering-and-exiting-proof-mode}}\label{\detokenize{proofs/writing-proofs/proof-mode:proof-editing-mode}}
\sphinxAtStartPar
Coq enters {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-proof-mode}]{\sphinxtermref{\DUrole{xref,std,std-term}{proof mode}}}} when you begin a proof through
commands such as {\hyperref[\detokenize{language/core/definitions:coq:cmd.Theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Goal}}}}}.  Coq user interfaces
usually have a way to indicate that you're in proof mode.

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:term-tactic}]{\sphinxtermref{\DUrole{xref,std,std-term}{Tactics}}}} are available only in proof mode (currently they give syntax
errors outside of proof mode).  Most {\hyperref[\detokenize{language/core/basic:term-command}]{\sphinxtermref{\DUrole{xref,std,std-term}{commands}}}} can be used both in and out of
proof mode, but some commands only work in or outside of proof mode.

\sphinxAtStartPar
When the proof is completed, you can exit proof mode with commands such as
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Save}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Save}}}}}.
\index{Goal (command)@\spxentry{Goal}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Goal~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
\sphinxAtStartPar
Asserts an unnamed proposition.  This is intended for quick tests that
a proposition is provable.  If the proof is eventually completed and
validated, you can assign a name with the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Save}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Save}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}
commands.  If no name is given, the name will be \sphinxcode{\sphinxupquote{Unnamed\_thm}} (or,
if that name is already defined, a variant of that).

\end{fulllineitems}\end{savenotes}

\index{Qed (command)@\spxentry{Qed}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Qed}}}}
\sphinxAtStartPar
Passes a completed {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-proof-term}]{\sphinxtermref{\DUrole{xref,std,std-term}{proof term}}}} to Coq's kernel
to check that the proof term is {\hyperref[\detokenize{language/core/basic:term-well-typed}]{\sphinxtermref{\DUrole{xref,std,std-term}{well\sphinxhyphen{}typed}}}} and
to verify that its type matches the theorem statement.  If it's verified, the
proof term is added to the global environment as an {\hyperref[\detokenize{language/core/conversion:term-opaque}]{\sphinxtermref{\DUrole{xref,std,std-term}{opaque}}}} constant
using the declared name from the original goal.

\sphinxAtStartPar
It's very rare for a proof term to fail verification.  Generally this
indicates a bug in a tactic you used or that you misused some
unsafe tactics.
\index{Attempt to save an incomplete proof (error)@\spxentry{Attempt to save an incomplete proof}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode: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}\end{savenotes}

\index{No focused proof (No proof\sphinxhyphen{}editing in progress) (error)@\spxentry{No focused proof (No proof\sphinxhyphen{}editing in progress)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode: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\sphinxhyphen{}editing~in~progress).}}}}
\sphinxAtStartPar
You tried to use a proof mode command such as {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} outside of proof
mode.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Sometimes an error occurs when building the proof term, because
tactics do not enforce completely the term construction
constraints.

\sphinxAtStartPar
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}

\end{fulllineitems}\end{savenotes}

\index{Save (command)@\spxentry{Save}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Save}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Save~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Similar to {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}, except that the proof term is added to the global
context with the name {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, which
overrides any name provided by the {\hyperref[\detokenize{language/core/definitions:coq:cmd.Theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} command or
its variants.

\end{fulllineitems}\end{savenotes}

\index{Defined (command)@\spxentry{Defined}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Defined~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Similar to {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Save}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Save}}}}}, except the proof is made
{\hyperref[\detokenize{language/core/conversion:term-transparent}]{\sphinxtermref{\DUrole{xref,std,std-term}{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{proofs/writing-proofs/equality:applyingconversionrules}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying conversion rules}}}},
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}}).  If {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is specified,
the proof is defined with the given name, which overrides any name
provided by the {\hyperref[\detokenize{language/core/definitions:coq:cmd.Theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} command or its variants.

\end{fulllineitems}\end{savenotes}

\index{Admitted (command)@\spxentry{Admitted}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Admitted}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Admitted}}}}
\sphinxAtStartPar
This command is available in proof mode to give up
the current proof and declare the initial goal as an axiom.

\end{fulllineitems}\end{savenotes}

\index{Abort (command)@\spxentry{Abort}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Abort}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Abort~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{All}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Cancels the current proof development, switching back to
the previous proof development, or to the Coq toplevel if no other
proof was being edited.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
Aborts editing the proof named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} for use when you have
nested proofs.  See also {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:flag.Nested-Proofs-Allowed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Nested Proofs Allowed}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{All}}}}] \leavevmode
\sphinxAtStartPar
Aborts all current proofs.

\end{description}
\index{No focused proof (No proof\sphinxhyphen{}editing in progress) (error)@\spxentry{No focused proof (No proof\sphinxhyphen{}editing in progress)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:id2}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~focused~proof~(No~proof\sphinxhyphen{}editing~in~progress).}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Proof `term` (command)@\spxentry{Proof `term`}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof-`term`}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This command applies in proof mode. It is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{exact {\hyperref[\detokenize{language/core/basic: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}}}}).

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
Use of this command is discouraged.  In particular, it
doesn't work in Proof General because it must
immediately follow the command that opened proof mode, but
Proof General inserts {\hyperref[\detokenize{language/core/basic:coq:cmd.Unset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unset}}}}} {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Silent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Silent}}}}} before it (see
\sphinxhref{https://github.com/ProofGeneral/PG/issues/498}{Proof General issue \#498}%
\begin{footnote}[22]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/ProofGeneral/PG/issues/498}
%
\end{footnote}).
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{Proof (command)@\spxentry{Proof}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof}}}}
\sphinxAtStartPar
Is a no\sphinxhyphen{}op which is useful to delimit the sequence of tactic commands
which start a proof, after a {\hyperref[\detokenize{language/core/definitions:coq:cmd.Theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} command. It is a good practice to
use {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}} as an opening parenthesis, closed in the script with a
closing {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Proof-with}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof with}}}}}



\end{fulllineitems}\end{savenotes}

\index{Proof using (command)@\spxentry{Proof using}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof-using}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-starred_ident_ref}]{\sphinxcrossref{\DUrole{hole}{starred\_ident\_ref}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr50}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr50}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr50}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr50}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr50}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}} \sphinxhyphen{} {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}} + {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-starred_ident_ref}]{\sphinxcrossref{\DUrole{hole}{starred\_ident\_ref}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}} ) \DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:grammar-token-starred_ident_ref}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-starred_ident_ref}]{\sphinxcrossref{\DUrole{hole}{starred\_ident\_ref}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Type \DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{All}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Opens proof mode, declaring the set of
section variables (see {\hyperref[\detokenize{language/core/assumptions:gallina-assumptions}]{\sphinxcrossref{\DUrole{std,std-ref}{Assumptions}}}}) used by the proof.
At {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} time, the
system verifies that the set of section variables used in
the proof is a subset of the declared one.

\sphinxAtStartPar
The set of declared variables is closed under type dependency. For
example, if \sphinxcode{\sphinxupquote{T}} is a variable and \sphinxcode{\sphinxupquote{a}} is a variable of type
\sphinxcode{\sphinxupquote{T}}, then the commands \sphinxcode{\sphinxupquote{Proof using a}} and \sphinxcode{\sphinxupquote{Proof using T a}}
are equivalent.

\sphinxAtStartPar
The set of declared variables always includes the variables used by
the statement. In other words \sphinxcode{\sphinxupquote{Proof using e}} is equivalent to
\sphinxcode{\sphinxupquote{Proof using Type + e}} for any declaration expression \sphinxcode{\sphinxupquote{e}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{} {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr50}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr50}}}}}}}}] \leavevmode
\sphinxAtStartPar
Use all section variables except those specified by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr50}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr50}}}}}}}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}} + {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}}}}}}] \leavevmode
\sphinxAtStartPar
Use section variables from the union of both collections.
See {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:nameaset}]{\sphinxcrossref{\DUrole{std,std-ref}{Name a set of section hypotheses for Proof using}}}} to see how to form a named collection.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}} \sphinxhyphen{} {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr0}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr0}}}}}}}}] \leavevmode
\sphinxAtStartPar
Use section variables which are in the first collection but not in the
second one.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Use the transitive closure of the specified collection.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{Type}}}}] \leavevmode
\sphinxAtStartPar
Use only section variables occurring in the statement.  Specifying \sphinxcode{\sphinxupquote{\DUrole{notation}{*}}}
uses the forward transitive closure of all the section variables occurring
in the statement. For example, if the variable \sphinxcode{\sphinxupquote{H}} has type \sphinxcode{\sphinxupquote{p < 5}} then
\sphinxcode{\sphinxupquote{H}} is in \sphinxcode{\sphinxupquote{p*}} since \sphinxcode{\sphinxupquote{p}} occurs in the type of \sphinxcode{\sphinxupquote{H}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{All}}}}] \leavevmode
\sphinxAtStartPar
Use all section variables.

\end{description}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:tactics-implicit-automation}]{\sphinxcrossref{\DUrole{std,std-ref}{Setting implicit automation tactics}}}}



\end{fulllineitems}\end{savenotes}

\index{using (attribute)@\spxentry{using}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:attr.using}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{using}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}} can be applied to the {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}, {\hyperref[\detokenize{language/core/definitions:coq:cmd.Example}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Example}}}}},
{\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} and {\hyperref[\detokenize{language/core/coinductive:coq:cmd.CoFixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}} commands as well as to {\hyperref[\detokenize{language/core/definitions:coq:cmd.Lemma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Lemma}}}}} and
its variants.  It takes
a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}}}}}, in quotes, as its value. This is equivalent to
specifying the same \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}}}}} in
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof-using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof using}}}}}.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Test}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{.}
    \PYG{n}{n} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{Hn} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{Hn} \PYG{k}{is} \PYG{n}{declared}


\PYG{o}{\PYGZsh{}}\PYG{o}{[}\PYG{k}{using}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Hn}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{]}
\PYG{k+kn}{Lemma} \PYG{n}{example} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{Hn} \PYG{o}{:} \PYG{n}{n} \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{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Abort}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{Test}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{Proof using options}
\label{\detokenize{proofs/writing-proofs/proof-mode:proof-using-options}}
\sphinxAtStartPar
The following options modify the behavior of \sphinxcode{\sphinxupquote{Proof using}}.
\index{Default Proof Using (option)@\spxentry{Default Proof Using}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Default-Proof-Using}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Default~Proof~Using~"{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}}"}}}}
\sphinxAtStartPar
Set this {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} to use \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}}}}} 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}\end{savenotes}

\index{Suggest Proof Using (flag)@\spxentry{Suggest Proof Using}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:flag.Suggest-Proof-Using}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Suggest~Proof~Using}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is on, {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} suggests
a \sphinxcode{\sphinxupquote{using}} annotation if the user did not provide one.

\end{fulllineitems}\end{savenotes}



\paragraph{Name a set of section hypotheses for \sphinxstyleliteralintitle{\sphinxupquote{Proof using}}}
\label{\detokenize{proofs/writing-proofs/proof-mode:name-a-set-of-section-hypotheses-for-proof-using}}\label{\detokenize{proofs/writing-proofs/proof-mode:nameaset}}\index{Collection (command)@\spxentry{Collection}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Collection}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Collection~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}}}}}}
\sphinxAtStartPar
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}

\sphinxAtStartPar
Define the collection named \sphinxcode{\sphinxupquote{Some}} containing \sphinxcode{\sphinxupquote{x}}, \sphinxcode{\sphinxupquote{y}} and \sphinxcode{\sphinxupquote{z}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Collection Some := x y z.
\end{sphinxVerbatim}

\sphinxAtStartPar
Define the collection named \sphinxcode{\sphinxupquote{Fewer}} containing only \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Collection Fewer := Some \PYGZhy{} z
\end{sphinxVerbatim}

\sphinxAtStartPar
Define the collection named \sphinxcode{\sphinxupquote{Many}} containing the set union or set
difference of \sphinxcode{\sphinxupquote{Fewer}} and \sphinxcode{\sphinxupquote{Some}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Collection Many := Fewer + Some
Collection Many := Fewer \PYGZhy{} Some
\end{sphinxVerbatim}

\sphinxAtStartPar
Define the collection named \sphinxcode{\sphinxupquote{Many}} containing the set difference of
\sphinxcode{\sphinxupquote{Fewer}} and the unnamed collection \sphinxcode{\sphinxupquote{x y}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Collection Many := Fewer \PYGZhy{} (x y)
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{Existential (command)@\spxentry{Existential}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Existential}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Existential~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This command instantiates an existential variable. {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} is an index in
the list of uninstantiated existential variables displayed by {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Existentials}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Existentials}}}}}.

\sphinxAtStartPar
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}}}}}.

\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.13.}

\end{fulllineitems}\end{savenotes}

\index{Grab Existential Variables (command)@\spxentry{Grab Existential Variables}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Grab-Existential-Variables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Grab~Existential~Variables}}}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.13: }Use {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Unshelve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unshelve}}}}} instead.

\end{fulllineitems}\end{savenotes}



\subsubsection{Proof modes}
\label{\detokenize{proofs/writing-proofs/proof-mode:proof-modes}}
\sphinxAtStartPar
When entering proof mode through commands such as {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Goal}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}},
Coq picks by default the \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ mode. Nonetheless, there exist other proof modes
shipped in the standard Coq installation, and furthermore some plugins define
their own proof modes. The default proof mode used when opening a proof can
be changed using the following option.
\index{Default Proof Mode (option)@\spxentry{Default Proof Mode}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Default-Proof-Mode}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Default~Proof~Mode~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} selects the proof mode to use when starting a proof. Depending on the proof
mode, various syntactic constructs are allowed when writing a
proof. All proof modes support commands; the proof mode determines
which tactic language and set of tactic definitions are available.  The
possible option values are:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{"Classic"}}}] \leavevmode
\sphinxAtStartPar
Activates the \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ language and the tactics with the syntax documented
in this manual.
Some tactics are not available until the associated plugin is loaded,
such as \sphinxcode{\sphinxupquote{SSR}} or \sphinxcode{\sphinxupquote{micromega}}.
This proof mode is set when the {\hyperref[\detokenize{language/coq-library:term-prelude}]{\sphinxtermref{\DUrole{xref,std,std-term}{prelude}}}} is loaded.

\item[{\sphinxcode{\sphinxupquote{"Noedit"}}}] \leavevmode
\sphinxAtStartPar
No tactic
language is activated at all. This is the default when the {\hyperref[\detokenize{language/coq-library:term-prelude}]{\sphinxtermref{\DUrole{xref,std,std-term}{prelude}}}}
is not loaded, e.g. through the \sphinxcode{\sphinxupquote{\sphinxhyphen{}noinit}} option for \sphinxcode{\sphinxupquote{coqc}}.

\item[{\sphinxcode{\sphinxupquote{"Ltac2"}}}] \leavevmode
\sphinxAtStartPar
Activates the Ltac2 language and the Ltac2\sphinxhyphen{}specific variants of the documented
tactics.
This value is only available after {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Requiring}}}}} Ltac2.
{\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Importing}}}}} Ltac2 sets this mode.

\end{description}

\sphinxAtStartPar
Some external plugins also define their own proof mode, which can be
activated with this command.

\end{fulllineitems}\end{savenotes}



\subsubsection{Navigation in the proof tree}
\label{\detokenize{proofs/writing-proofs/proof-mode:navigation-in-the-proof-tree}}\index{Undo (command)@\spxentry{Undo}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Undo}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Undo~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{To}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Cancels the effect of the last {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} commands or tactics.
The \sphinxcode{\sphinxupquote{\DUrole{notation}{To {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} form goes back to the specified state number.
If {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} is not specified, the command goes back one command or tactic.

\end{fulllineitems}\end{savenotes}

\index{Restart (command)@\spxentry{Restart}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Restart}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Restart}}}}
\sphinxAtStartPar
Restores the proof to the original goal.
\index{No focused proof to restart (error)@\spxentry{No focused proof to restart}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode: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{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Focus (command)@\spxentry{Focus}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Focus}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Focus~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Focuses the attention on the first goal to prove or, if {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} is
specified, the {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}\sphinxhyphen{}th.  The
printing of the other goals is suspended until the focused goal
is solved or unfocused.

\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.8: }Prefer the use of bullets or focusing brackets with a goal selector (see below).

\end{fulllineitems}\end{savenotes}

\index{Unfocus (command)@\spxentry{Unfocus}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Unfocus}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unfocus}}}}
\sphinxAtStartPar
This command restores to focus the goal that were suspended by the
last {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Focus}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Focus}}}}} command.

\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.8.}

\end{fulllineitems}\end{savenotes}

\index{Unfocused (command)@\spxentry{Unfocused}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Unfocused}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unfocused}}}}
\sphinxAtStartPar
Succeeds if the proof is fully unfocused, fails if there are some
goals out of focus.

\end{fulllineitems}\end{savenotes}

\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:curly-braces}}\index{\sphinxleftcurlybrace{} (tactic)@\spxentry{\sphinxleftcurlybrace{}}\spxextra{tactic}}\index{\sphinxrightcurlybrace{} (tactic)@\spxentry{\sphinxrightcurlybrace{}}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn._}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[}~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{]}}}~:}\DUrole{notation-sup}{?}}~\{}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn._}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\}}}}}~
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\{}} (without a terminating period) focuses on the first
goal.  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.

\sphinxAtStartPar
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{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}:}}}}] \leavevmode
\sphinxAtStartPar
Focuses on the {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}\sphinxhyphen{}th goal to prove.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}: \{}}}}] \leavevmode
\sphinxAtStartPar
Focuses on the named goal {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{description}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Goals are just existential variables and existential variables do not
get a name by default. You can give a name to a goal by using \sphinxcode{\sphinxupquote{\DUrole{notation}{refine ?{[}{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}{]}}}}.
You may also wrap this in an Ltac\sphinxhyphen{}definition like:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{name\PYGZus{}goal} \PYG{n}{name} \PYG{o}{:=} \PYG{k}{refine} \PYG{o}{?}\PYG{o}{[}\PYG{n}{name}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{language/extensions/evars:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}



\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
This first example uses the Ltac definition above, and the named goals
only serve for documentation.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{n}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{induction} \PYG{n}{n}\PYG{o}{;} \PYG{o}{[} \PYG{n}{name\PYGZus{}goal} \PYG{n}{base} \PYG{o}{|} \PYG{n}{name\PYGZus{}goal} \PYG{n}{step} \PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{l+m+mi}{0}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n}

\PYG{o}{[}\PYG{n}{base}\PYG{o}{]}\PYG{o}{:} \PYG{o}{\PYGZob{}}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{l+m+mi}{0}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{reflexivity}\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}{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}{goal}
    
    \PYG{n}{goal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{\PYGZcb{}}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{[}\PYG{n}{step}\PYG{o}{]}\PYG{o}{:} \PYG{o}{\PYGZob{}}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{IHn} \PYG{o}{:} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0} \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}{n} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{simpl}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{IHn} \PYG{o}{:} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0} \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{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n}

\PYG{n}{f\PYGZus{}equal}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{IHn} \PYG{o}{:} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0} \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}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{n}

\PYG{k+kp}{assumption}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{o}{\PYGZcb{}}
\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This can also be a way of focusing on a shelved goal, for instance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{exists} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n}

\PYG{n}{eexists} \PYG{o}{?}\PYG{o}{[}\PYG{n}{x}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{goal}
    \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}{x} \PYG{o}{=} \PYG{o}{?}\PYG{n}{x}

\PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{k+kn}{All} \PYG{n}{the} \PYG{n}{remaining} \PYG{n}{goals} \PYG{n}{are} \PYG{n}{on} \PYG{n}{the} \PYG{n}{shelf}\PYG{o}{.}
    
    \PYG{l+m+mi}{1} \PYG{n}{goal}
    
    \PYG{n}{goal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{nat}

\PYG{o}{[}\PYG{n}{x}\PYG{o}{]}\PYG{o}{:} \PYG{k+kp}{exact} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{This proof is focused, but cannot be unfocused this way (error)@\spxentry{This proof is focused, but cannot be unfocused this way}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode: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.}}}}
\sphinxAtStartPar
You are trying to use \sphinxcode{\sphinxupquote{\}}} but the current subproof has not been fully solved.

\end{fulllineitems}\end{savenotes}

\index{No such goal (‘natural’) (error)@\spxentry{No such goal (‘natural’)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.No-such-goal-(_u2018natural_u2019)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal~({\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}).}}}}
\end{fulllineitems}\end{savenotes}

\index{No such goal (‘ident’) (error)@\spxentry{No such goal (‘ident’)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.No-such-goal-(_u2018ident_u2019)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}).}}}}
\end{fulllineitems}\end{savenotes}

\index{Brackets do not support multi\sphinxhyphen{}goal selectors (error)@\spxentry{Brackets do not support multi\sphinxhyphen{}goal selectors}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.Brackets-do-not-support-multi-goal-selectors}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Brackets~do~not~support~multi\sphinxhyphen{}goal~selectors.}}}}
\sphinxAtStartPar
Brackets are used to focus on a single goal given either by its position
or by its name if it has one.

\end{fulllineitems}\end{savenotes}



\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
The error messages for bullets below.



\end{fulllineitems}\end{savenotes}



\paragraph{Bullets}
\label{\detokenize{proofs/writing-proofs/proof-mode:bullets}}\label{\detokenize{proofs/writing-proofs/proof-mode:id3}}
\sphinxAtStartPar
Alternatively, proofs can be structured with bullets instead of \sphinxcode{\sphinxupquote{\{}} and \sphinxcode{\sphinxupquote{\}}}. 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.

\sphinxAtStartPar
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{\sphinxhyphen{}}}, \sphinxcode{\sphinxupquote{+}} or \sphinxcode{\sphinxupquote{*}} symbols:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{+}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{+}\DUrole{notation-sup}{+}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{+}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
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:}
\sphinxAtStartPar
In Proof General (\sphinxcode{\sphinxupquote{Emacs}} interface to Coq), you must use
bullets with the priority ordering shown above to have a correct
indentation. For example \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} must be the outer bullet and \sphinxcode{\sphinxupquote{**}} the inner
one in the example below.
\end{sphinxadmonition}

\sphinxAtStartPar
The following example script illustrates all these features:

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
    
    \PYG{n}{goal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{goal} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
    
    \PYG{n}{goal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{goal} \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}{goals}
    
    \PYG{n}{goal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
    
    \PYG{n}{goal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{goal} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
    
    \PYG{n}{goal} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{\PYGZob{}} \PYG{k}{trivial}\PYG{o}{.} \PYG{o}{\PYGZcb{}}
\PYG{k+kp}{assumption}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
    
    \PYG{n}{goal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Wrong bullet ‘bullet’: Current bullet ‘bullet’ is not finished (error)@\spxentry{Wrong bullet ‘bullet’: Current bullet ‘bullet’ is not finished}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.Wrong-bullet-_u2018bullet_u2019:-Current-bullet-_u2018bullet_u2019-is-not-finished}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Wrong~bullet~{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{1}}$}}}}:~Current~bullet~{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{2}}$}}}}~is~not~finished.}}}}
\sphinxAtStartPar
Before using bullet \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode: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{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{2}}$}}}}}}} may be the same.

\end{fulllineitems}\end{savenotes}

\index{Wrong bullet ‘bullet’: Bullet ‘bullet’ is mandatory here (error)@\spxentry{Wrong bullet ‘bullet’: Bullet ‘bullet’ is mandatory here}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.Wrong-bullet-_u2018bullet_u2019:-Bullet-_u2018bullet_u2019-is-mandatory-here}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Wrong~bullet~{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{1}}$}}}}:~Bullet~{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{2}}$}}}}~is~mandatory~here.}}}}
\sphinxAtStartPar
You must put \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{2}}$}}}}}}} to focus on the next goal. No other bullet is
allowed here.

\end{fulllineitems}\end{savenotes}

\index{No such goal. Focus next goal with bullet ‘bullet’ (error)@\spxentry{No such goal. Focus next goal with bullet ‘bullet’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.No-such-goal.-Focus-next-goal-with-bullet-_u2018bullet_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.~Focus~next~goal~with~bullet~{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet}}}}.}}}}
\sphinxAtStartPar
You tried to apply a tactic but no goals were under focus.
Using \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet}}}}}}} is  mandatory here.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.~Try~unfocusing~with~\}.}}}}
\sphinxAtStartPar
You just finished a goal focused by \sphinxcode{\sphinxupquote{\{}}, you must unfocus it with \sphinxcode{\sphinxupquote{\}}}.

\end{fulllineitems}\end{savenotes}



\subparagraph{Mandatory Bullets}
\label{\detokenize{proofs/writing-proofs/proof-mode:mandatory-bullets}}
\sphinxAtStartPar
Using {\hyperref[\detokenize{proof-engine/tactics:coq:opt.Default-Goal-Selector}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Default Goal Selector}}}}} with the \sphinxcode{\sphinxupquote{!}} selector forces
tactic scripts to keep focus to exactly one goal (e.g. using bullets)
or use explicit goal selectors.


\subparagraph{Set Bullet Behavior}
\label{\detokenize{proofs/writing-proofs/proof-mode:set-bullet-behavior}}\index{Bullet Behavior (option)@\spxentry{Bullet Behavior}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Bullet-Behavior}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bullet~Behavior~\DUrole{alternative}{\DUrole{alternative-block}{"None"}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{"Strict~Subproofs"}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} controls the bullet behavior and can take two possible values:
\begin{itemize}
\item {} 
\sphinxAtStartPar
"None": this makes bullets inactive.

\item {} 
\sphinxAtStartPar
"Strict Subproofs": this makes bullets active (this is the default behavior).

\end{itemize}

\end{fulllineitems}\end{savenotes}



\paragraph{Modifying the order of goals}
\label{\detokenize{proofs/writing-proofs/proof-mode:modifying-the-order-of-goals}}\index{cycle (tactic)@\spxentry{cycle}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.cycle}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cycle~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-int_or_var}]{\sphinxcrossref{\DUrole{hole}{int\_or\_var}}}}}}}}
\sphinxAtStartPar
Reorders the selected goals so that the first \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}} goals appear after the
other selected goals.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}} is negative, it puts the last \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}} goals at the
beginning of the list.
The tactic is only useful with a goal selector, most commonly \sphinxcode{\sphinxupquote{all:}}.
Note that other selectors reorder goals; \sphinxcode{\sphinxupquote{1,3: cycle 1}} is not equivalent
to \sphinxcode{\sphinxupquote{all: cycle 1}}.  See {\hyperref[\detokenize{proof-engine/ltac:coq:tacn._u2026-:-_u2026-(goal-selector)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{… : … (goal selector)}}}}}.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{goal} \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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{5}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
    \PYG{n}{goal} \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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{goal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{swap (tactic)@\spxentry{swap}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.swap}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{swap~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-int_or_var}]{\sphinxcrossref{\DUrole{hole}{int\_or\_var}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-int_or_var}]{\sphinxcrossref{\DUrole{hole}{int\_or\_var}}}}}}}}
\sphinxAtStartPar
Exchanges the position of the specified goals.
Negative values for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}} indicate counting goals
backward from the end of the list of selected goals. Goals are indexed from 1.
The tactic is only useful with a goal selector, most commonly \sphinxcode{\sphinxupquote{all:}}.
Note that other selectors reorder goals; \sphinxcode{\sphinxupquote{1,3: swap 1 3}} is not equivalent
to \sphinxcode{\sphinxupquote{all: swap 1 3}}.  See {\hyperref[\detokenize{proof-engine/ltac:coq:tacn._u2026-:-_u2026-(goal-selector)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{… : … (goal selector)}}}}}.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{goal} \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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{goal} \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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{goal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{revgoals (tactic)@\spxentry{revgoals}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.revgoals}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{revgoals}}}}
\sphinxAtStartPar
Reverses the order of the selected goals.  The tactic is only useful with a goal
selector, most commonly \sphinxcode{\sphinxupquote{all :}}.   Note that other selectors reorder goals;
\sphinxcode{\sphinxupquote{1,3: revgoals}} is not equivalent to \sphinxcode{\sphinxupquote{all: revgoals}}.  See {\hyperref[\detokenize{proof-engine/ltac:coq:tacn._u2026-:-_u2026-(goal-selector)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{… : … (goal selector)}}}}}.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{goal} \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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{goal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{Postponing the proof of some goals}
\label{\detokenize{proofs/writing-proofs/proof-mode:postponing-the-proof-of-some-goals}}
\sphinxAtStartPar
Goals can be \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-shelved}}shelved} so they are no longer displayed in the proof state.
They can then be \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:term-unshelved}}unshelved} to make them visible again.
\index{shelve (tactic)@\spxentry{shelve}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.shelve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{shelve}}}}
\sphinxAtStartPar
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{proofs/writing-proofs/proof-mode:coq:cmd.Unshelve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unshelve}}}}}.
\index{shelve\_unifiable (tactic)@\spxentry{shelve\_unifiable}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.shelve_unifiable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{shelve\_unifiable}}}}
\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goal}
    \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}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Unshelve (command)@\spxentry{Unshelve}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Unshelve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unshelve}}}}
\sphinxAtStartPar
This command moves all the goals on the shelf (see {\hyperref[\detokenize{proofs/writing-proofs/proof-mode: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}\end{savenotes}

\index{unshelve (tactic)@\spxentry{unshelve}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.unshelve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unshelve~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}}}}}}
\sphinxAtStartPar
Performs \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}, then unshelves existential variables added to the
shelf by the execution of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}, prepending them to the current goal.

\end{fulllineitems}\end{savenotes}

\index{give\_up (tactic)@\spxentry{give\_up}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.give_up}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{give\_up}}}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{give\_up}} tactic can be used while editing a proof, to choose to
write the proof script in a non\sphinxhyphen{}sequential order.

\end{fulllineitems}\end{savenotes}



\subsubsection{Requesting information}
\label{\detokenize{proofs/writing-proofs/proof-mode:requesting-information}}\label{\detokenize{proofs/writing-proofs/proof-mode:requestinginformation}}\index{Show (command)@\spxentry{Show}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Displays the current goals.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}] \leavevmode
\sphinxAtStartPar
Display only the {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}\sphinxhyphen{}th goal.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
Displays the named goal {\hyperref[\detokenize{language/core/basic: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/extensions/evars:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}) as in the following example.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goal}
    \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}{goal} \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{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{description}
\index{No focused proof (error)@\spxentry{No focused proof}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.No-focused-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~focused~proof.}}}}
\end{fulllineitems}\end{savenotes}

\index{No such goal (error)@\spxentry{No such goal}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.No-such-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Show Proof (command)@\spxentry{Show Proof}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Proof~\DUrole{repeat-wrapper}{\DUrole{repeat}{Diffs~\DUrole{repeat-wrapper}{\DUrole{repeat}{removed}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Displays the proof term generated by the tactics
that have been applied so far. If the proof is incomplete, the term
will contain holes, which correspond to subterms which are still to be
constructed. Each hole is an existential variable, which appears as a
question mark followed by an identifier.

\sphinxAtStartPar
Specifying “Diffs” highlights the difference between the
current and previous proof step.  By default, the command shows the
output once with additions highlighted.  Including “removed” shows
the output twice: once showing removals and once showing additions.
It does not examine the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Diffs}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Diffs}}}}} option.  See {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:id5}]{\sphinxcrossref{\DUrole{std,std-ref}{"Show Proof" differences}}}}.

\end{fulllineitems}\end{savenotes}

\index{Show Conjectures (command)@\spxentry{Show Conjectures}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Conjectures}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Conjectures}}}}
\sphinxAtStartPar
Prints 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, there may
be multiple names.

\end{fulllineitems}\end{savenotes}

\index{Show Intro (command)@\spxentry{Show Intro}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Intro}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Intro}}}}
\sphinxAtStartPar
If the current goal begins by at least one product,
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\sphinxhyphen{}product
goal, it prints nothing.

\end{fulllineitems}\end{savenotes}

\index{Show Intros (command)@\spxentry{Show Intros}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Intros}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Intros}}}}
\sphinxAtStartPar
Similar to the previous command.
Simulates the naming process of {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Show Existentials (command)@\spxentry{Show Existentials}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Existentials}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Existentials}}}}
\sphinxAtStartPar
Displays all open goals / existential variables in the current proof
along with the context and type of each variable.

\end{fulllineitems}\end{savenotes}

\index{Show Match (command)@\spxentry{Show Match}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Match}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Match~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Displays a template of the Gallina {\hyperref[\detokenize{language/core/variants:grammar-token-term_match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}}
construct with a branch for each constructor of the type
{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}.  This is used internally by
\sphinxhref{https://github.com/cpitclaudel/company-coq}{company\sphinxhyphen{}coq}%
\begin{footnote}[23]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/cpitclaudel/company-coq}
%
\end{footnote}.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show} \PYG{n}{Match} \PYG{n}{nat}\PYG{o}{.}
    \PYG{k}{match} \PYG{o}{\PYGZsh{}} \PYG{k}{with}
     \PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}}
     \PYG{o}{|} \PYG{n}{S} \PYG{n}{x} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{end}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Unknown inductive type (error)@\spxentry{Unknown inductive type}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:exn.Unknown-inductive-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unknown~inductive~type.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Show Universes (command)@\spxentry{Show Universes}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Universes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Universes}}}}
\sphinxAtStartPar
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{savenotes}

\index{Show Goal (command)@\spxentry{Show Goal}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Goal~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~at~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
Available in coqtop.  Displays a goal at a
proof state using the goal ID number and the proof state ID number.
It is primarily for use by tools such as Prooftree that need to fetch
goal history in this way.  Prooftree is a tool for visualizing a proof
as a tree that runs in Proof General.

\end{fulllineitems}\end{savenotes}

\index{Guarded (command)@\spxentry{Guarded}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Guarded}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Guarded}}}}
\sphinxAtStartPar
Some tactics (e.g. {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}) allow to build proofs using
fixpoint or co\sphinxhyphen{}fixpoint constructions. Due to the incremental nature
of 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.

\sphinxAtStartPar
The command {\hyperref[\detokenize{proofs/writing-proofs/proof-mode: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}\end{savenotes}



\subsubsection{Showing differences between proof steps}
\label{\detokenize{proofs/writing-proofs/proof-mode:showing-differences-between-proof-steps}}\label{\detokenize{proofs/writing-proofs/proof-mode:showing-diffs}}
\sphinxAtStartPar
Coq can automatically highlight the differences between successive proof steps
and between values in some error messages.  Coq can also highlight differences
in the proof term.
For example, the following screenshots of CoqIDE and coqtop show the application
of the same {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}} tactic.  The tactic creates two new hypotheses, highlighted in green.
The conclusion is entirely in pale green because although it’s changed, no tokens were added
to it.  The second screenshot uses the "removed" option, so it shows the conclusion a
second time with the old text, with deletions marked in red.  Also, since the hypotheses are
new, no line of old text is shown for them.
\begin{quote}

\noindent\sphinxincludegraphics{{diffs-coqide-on}.png}
\end{quote}
\begin{quote}

\noindent\sphinxincludegraphics{{diffs-coqide-removed}.png}
\end{quote}
\begin{quote}

\noindent\sphinxincludegraphics{{diffs-coqtop-on3}.png}
\end{quote}

\sphinxAtStartPar
This image shows an error message with diff highlighting in CoqIDE:
\begin{quote}

\noindent\sphinxincludegraphics{{diffs-error-message}.png}
\end{quote}


\paragraph{How to enable diffs}
\label{\detokenize{proofs/writing-proofs/proof-mode:how-to-enable-diffs}}\index{Diffs (option)@\spxentry{Diffs}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Diffs}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Diffs~\DUrole{alternative}{\DUrole{alternative-block}{"on"}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{"off"}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{"removed"}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} is used to enable diffs.
The “on” setting highlights added tokens in green, while the “removed” setting
additionally reprints items with removed tokens in red.  Unchanged tokens in
modified items are shown with pale green or red.  Diffs in error messages
use red and green for the compared values; they appear regardless of the setting.
(Colors are user\sphinxhyphen{}configurable.)

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
For coqtop, showing diffs can be enabled when starting coqtop with the
\sphinxcode{\sphinxupquote{\sphinxhyphen{}diffs on|off|removed}} command\sphinxhyphen{}line option or by setting the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Diffs}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Diffs}}}}} option
within Coq.  You will need to provide the \sphinxcode{\sphinxupquote{\sphinxhyphen{}color on|auto}} command\sphinxhyphen{}line option when
you start coqtop in either case.

\sphinxAtStartPar
Colors for coqtop can be configured by setting the \sphinxcode{\sphinxupquote{COQ\_COLORS}} environment
variable.  See section {\hyperref[\detokenize{practical-tools/coq-commands:customization-by-environment-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{By environment variables}}}}.  Diffs
use the tags \sphinxcode{\sphinxupquote{diff.added}}, \sphinxcode{\sphinxupquote{diff.added.bg}}, \sphinxcode{\sphinxupquote{diff.removed}} and \sphinxcode{\sphinxupquote{diff.removed.bg}}.

\sphinxAtStartPar
In CoqIDE, diffs should be enabled from the \sphinxcode{\sphinxupquote{View}} menu.  Don’t use the \sphinxcode{\sphinxupquote{Set Diffs}}
command in CoqIDE.  You can change the background colors shown for diffs from the
\sphinxcode{\sphinxupquote{Edit | Preferences | Tags}} panel by changing the settings for the \sphinxcode{\sphinxupquote{diff.added}},
\sphinxcode{\sphinxupquote{diff.added.bg}}, \sphinxcode{\sphinxupquote{diff.removed}} and \sphinxcode{\sphinxupquote{diff.removed.bg}} tags.  This panel also
lets you control other attributes of the highlights, such as the foreground
color, bold, italic, underline and strikeout.

\sphinxAtStartPar
Proof General can also display Coq\sphinxhyphen{}generated proof diffs automatically.
Please see the PG documentation section
"\sphinxhref{https://proofgeneral.github.io/doc/master/userman/Coq-Proof-General\#Showing-Proof-Diffs}{Showing Proof Diffs"}%
\begin{footnote}[24]\sphinxAtStartFootnote
\sphinxnolinkurl{https://proofgeneral.github.io/doc/master/userman/Coq-Proof-General\#Showing-Proof-Diffs}
%
\end{footnote})
for details.


\paragraph{How diffs are calculated}
\label{\detokenize{proofs/writing-proofs/proof-mode:how-diffs-are-calculated}}
\sphinxAtStartPar
Diffs are calculated as follows:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
Select the old proof state to compare to, which is the proof state before
the last tactic that changed the proof.  Changes that only affect the view
of the proof, such as \sphinxcode{\sphinxupquote{all: swap 1 2}}, are ignored.

\item {} 
\sphinxAtStartPar
For each goal in the new proof state, determine what old goal to compare
it to—the one it is derived from or is the same as.  Match the hypotheses by
name (order is ignored), handling compacted items specially.

\item {} 
\sphinxAtStartPar
For each hypothesis and conclusion (the “items”) in each goal, pass
them as strings to the lexer to break them into tokens.  Then apply the
Myers diff algorithm {[}\hyperlink{cite.zebibliography:id39}{Mye86}{]} on the tokens and add appropriate highlighting.

\end{enumerate}

\sphinxAtStartPar
Notes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Aside from the highlights, output for the "on" option should be identical
to the undiffed output.

\item {} 
\sphinxAtStartPar
Goals completed in the last proof step will not be shown even with the
"removed" setting.

\end{itemize}

\sphinxAtStartPar
This screen shot shows the result of applying a {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.split}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{split}}}}} tactic that replaces one goal
with 2 goals.  Notice that the goal \sphinxcode{\sphinxupquote{P 1}} is not highlighted at all after
the split because it has not changed.
\begin{quote}

\noindent\sphinxincludegraphics{{diffs-coqide-multigoal}.png}
\end{quote}

\sphinxAtStartPar
Diffs may appear like this after applying a {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} tactic that results
in a compacted hypotheses:
\begin{quote}

\noindent\sphinxincludegraphics{{diffs-coqide-compacted}.png}
\end{quote}


\paragraph{"Show Proof" differences}
\label{\detokenize{proofs/writing-proofs/proof-mode:show-proof-differences}}\label{\detokenize{proofs/writing-proofs/proof-mode:id5}}
\sphinxAtStartPar
To show differences in the proof term:
\begin{itemize}
\item {} 
\sphinxAtStartPar
In coqtop and Proof General, use the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Proof}}}}} \sphinxcode{\sphinxupquote{Diffs}} command.

\item {} 
\sphinxAtStartPar
In CoqIDE, position the cursor on or just after a tactic to compare the proof term
after the tactic with the proof term before the tactic, then select
\sphinxcode{\sphinxupquote{View / Show Proof}} from the menu or enter the associated key binding.
Differences will be shown applying the current \sphinxcode{\sphinxupquote{Show Diffs}} setting
from the \sphinxcode{\sphinxupquote{View}} menu.  If the current setting is \sphinxcode{\sphinxupquote{Don't show diffs}}, diffs
will not be shown.

\sphinxAtStartPar
Output with the "added and removed" option looks like this:
\begin{quote}

\noindent\sphinxincludegraphics{{diffs-show-proof}.png}
\end{quote}

\end{itemize}


\subsubsection{Controlling proof mode}
\label{\detokenize{proofs/writing-proofs/proof-mode:controlling-proof-mode}}\index{Hyps Limit (option)@\spxentry{Hyps Limit}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Hyps-Limit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hyps~Limit~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{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}\end{savenotes}

\index{Nested Proofs Allowed (flag)@\spxentry{Nested Proofs Allowed}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:flag.Nested-Proofs-Allowed}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nested~Proofs~Allowed}}}}
\sphinxAtStartPar
When turned on (it is off by default), this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} enables support for nested
proofs: a new assertion command can be inserted before the current proof is
finished, in which case Coq will temporarily switch to the proof of this
\sphinxstyleemphasis{nested lemma}. When the proof of the nested lemma is finished (with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}
or {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}), its statement will be made available (as if it had been
proved before starting the previous proof) and Coq will switch back to the
proof of the previous assertion.

\end{fulllineitems}\end{savenotes}

\index{Printing Goal Names (flag)@\spxentry{Printing Goal Names}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:flag.Printing-Goal-Names}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Goal~Names}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is turned on, the name of the goal is printed in
proof mode, which can be useful in cases of cross references
between goals.

\end{fulllineitems}\end{savenotes}



\subsubsection{Controlling memory usage}
\label{\detokenize{proofs/writing-proofs/proof-mode:controlling-memory-usage}}\index{Print Debug GC (command)@\spxentry{Print Debug GC}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Print-Debug-GC}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Debug~GC}}}}
\sphinxAtStartPar
Prints heap usage statistics, which are values from the \sphinxcode{\sphinxupquote{stat}} type of the \sphinxcode{\sphinxupquote{Gc}} module
described
\sphinxhref{https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html\#TYPEstat}{here}%
\begin{footnote}[25]\sphinxAtStartFootnote
\sphinxnolinkurl{https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html\#TYPEstat}
%
\end{footnote}
in the OCaml documentation.
The \sphinxcode{\sphinxupquote{live\_words}}, \sphinxcode{\sphinxupquote{heap\_words}} and \sphinxcode{\sphinxupquote{top\_heap\_words}} values give the basic information.
Words are 8 bytes or 4 bytes, respectively, for 64\sphinxhyphen{} and 32\sphinxhyphen{}bit executables.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
When experiencing high memory usage the following commands can be used
to force Coq to optimize some of its internal data structures.
\index{Optimize Proof (command)@\spxentry{Optimize Proof}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Optimize-Proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Optimize~Proof}}}}
\sphinxAtStartPar
Shrink the data structure used to represent the current proof.

\end{fulllineitems}\end{savenotes}

\index{Optimize Heap (command)@\spxentry{Optimize Heap}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Optimize-Heap}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Optimize~Heap}}}}
\sphinxAtStartPar
Perform a heap compaction.  This is generally an expensive operation.
See: \sphinxhref{http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html\#VALcompact}{OCaml Gc.compact}%
\begin{footnote}[26]\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}\end{savenotes}


\sphinxAtStartPar
Memory usage parameters can be set through the {\hyperref[\detokenize{practical-tools/coq-commands:ocamlrunparam}]{\sphinxcrossref{\DUrole{std,std-ref}{OCAMLRUNPARAM}}}}
environment variable.


\subsection{Tactics}
\label{\detokenize{proof-engine/tactics:tactics}}\label{\detokenize{proof-engine/tactics:id1}}\label{\detokenize{proof-engine/tactics::doc}}
\sphinxAtStartPar
Tactics specify how to transform the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-proof-state}]{\sphinxtermref{\DUrole{xref,std,std-term}{proof state}}}} of an
incomplete proof to eventually generate a complete proof.

\sphinxAtStartPar
Proofs can be developed in two basic ways: In \DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/tactics:term-forward-reasoning}}forward reasoning},
the proof begins by proving simple statements that are then combined to prove the
theorem statement as the last step of the proof. With forward reasoning,
for example,
the proof of \sphinxcode{\sphinxupquote{A /\textbackslash{} B}} would begin with proofs of \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{B}}, which are
then used to prove \sphinxcode{\sphinxupquote{A /\textbackslash{} B}}.  Forward reasoning is probably the most common
approach in human\sphinxhyphen{}generated proofs.

\sphinxAtStartPar
In \DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/tactics:term-backward-reasoning}}backward reasoning}, the proof begins with the theorem statement
as the goal, which is then gradually transformed until every subgoal generated
along the way has been proven.  In this case, the proof of \sphinxcode{\sphinxupquote{A /\textbackslash{} B}} begins
with that formula as the goal.  This can be transformed into two subgoals,
\sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{B}}, followed by the proofs of \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{B}}.  Coq and its tactics
use backward reasoning.

\sphinxAtStartPar
A tactic may fully prove a goal, in which case the goal is removed
from the proof state.
More commonly, a tactic replaces a goal with one or more {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:term-subgoal}]{\sphinxtermref{\DUrole{xref,std,std-term}{subgoals}}}}.
(We say that a tactic reduces a goal to its subgoals.)

\sphinxAtStartPar
Most tactics require specific elements or preconditions to reduce a goal;
they display error messages if they can't be applied to the goal.
A few tactics, such as {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}, don't fail even if the proof state
is unchanged.

\sphinxAtStartPar
Goals are identified by number. The current goal is number
1. Tactics are applied to the current goal by default.  (The
default can be changed with the {\hyperref[\detokenize{proof-engine/tactics:coq:opt.Default-Goal-Selector}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Default Goal Selector}}}}}
option.)  They can
be applied to another goal or to multiple goals with a
{\hyperref[\detokenize{proof-engine/ltac:goal-selectors}]{\sphinxcrossref{\DUrole{std,std-ref}{goal selector}}}} such as \sphinxcode{\sphinxupquote{\DUrole{notation}{2: {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}.

\sphinxAtStartPar
This chapter describes many of the most common built\sphinxhyphen{}in tactics.
Built\sphinxhyphen{}in tactics can be combined to form tactic expressions, which are
described in the {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac}}}} chapter.  Since tactic expressions can
be used anywhere that a built\sphinxhyphen{}in tactic can be used, "tactic" may
refer to both built\sphinxhyphen{}in tactics and tactic expressions.


\subsubsection{Common elements of tactics}
\label{\detokenize{proof-engine/tactics:common-elements-of-tactics}}

\paragraph{Reserved keywords}
\label{\detokenize{proof-engine/tactics:reserved-keywords}}
\sphinxAtStartPar
The tactics described in this chapter reserve the following keywords:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
by using
\end{sphinxVerbatim}

\sphinxAtStartPar
Thus, these keywords cannot be used as identifiers. It also declares
the following character sequences as tokens:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
** [= |\PYGZhy{}
\end{sphinxVerbatim}


\paragraph{Invocation of tactics}
\label{\detokenize{proof-engine/tactics:invocation-of-tactics}}\label{\detokenize{proof-engine/tactics:id2}}
\sphinxAtStartPar
A tactic is applied as an ordinary command. It may be preceded by a
goal selector (see Section {\hyperref[\detokenize{proof-engine/ltac:goal-selectors}]{\sphinxcrossref{\DUrole{std,std-ref}{Goal selectors}}}}). If no selector is
specified, the default selector is used.

\phantomsection\label{\detokenize{proof-engine/tactics:tactic-invocation-grammar}}\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-tactic_invocation}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-tactic_invocation}]{\sphinxcrossref{\DUrole{hole}{tactic\_invocation}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-toplevel_selector}]{\sphinxcrossref{\DUrole{hole}{toplevel\_selector}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}.}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}.}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}
\index{Default Goal Selector (option)@\spxentry{Default Goal Selector}\spxextra{option}}

\begin{savenotes}\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}}}}"}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} controls the default selector, used when no selector is
specified when applying a tactic. The initial value is 1, hence the
tactics are, by default, applied to the first goal.

\sphinxAtStartPar
Using value \sphinxcode{\sphinxupquote{all}} will make it 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}}.

\sphinxAtStartPar
Using value \sphinxcode{\sphinxupquote{!}} enforces that all tactics are used either on a
single focused goal or with a local selector (’’strict focusing
mode’’).

\sphinxAtStartPar
Although other selectors are available, only \sphinxcode{\sphinxupquote{all}}, \sphinxcode{\sphinxupquote{!}} or a
single natural number are valid default goal selectors.

\end{fulllineitems}\end{savenotes}



\paragraph{Bindings}
\label{\detokenize{proof-engine/tactics:bindings}}\label{\detokenize{proof-engine/tactics:id3}}
\sphinxAtStartPar
Tactics that take a term as an argument may also accept {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bindings}}}}}
to instantiate some parameters of the term by name or position.
The general form of a term with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bindings}}}}} is
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{tac}}$}}}} with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}} where {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bindings}}}}} can take two different forms:
\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-bindings}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
In the first form, if an {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is specified, it must be bound in the
type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and provides the tactic with an instance for the
parameter of this name. If a {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} is specified, it refers to
the \sphinxcode{\sphinxupquote{n}}\sphinxhyphen{}th non dependent premise of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{tac}}$}}}}}}}.
\index{No such binder (error)@\spxentry{No such binder}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}


\item {} 
\sphinxAtStartPar
In the second form, the interpretation of the {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s depend on which
tactic they appear in.  For {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.elim}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim}}}}}
and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}}, the {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s
provide instances for all the dependent products in the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{tac}}$}}}}}}} while in
the case of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}, or of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.constructor}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{constructor}}}}} and its variants, only instances
for the dependent products that are not bound in the conclusion of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{tac}}$}}}}}}}
are required.
\index{Not the right number of missing arguments (error)@\spxentry{Not the right number of missing arguments}\spxextra{error}}

\begin{savenotes}\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{savenotes}


\end{itemize}


\paragraph{Intro patterns}
\label{\detokenize{proof-engine/tactics:intro-patterns}}\label{\detokenize{proof-engine/tactics:intropatterns}}
\sphinxAtStartPar
Intro patterns let you specify the name to assign to variables and hypotheses
introduced by tactics.  They also let you split an introduced hypothesis into
multiple hypotheses or subgoals.  Common tactics that accept intro patterns
include {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-intropattern_list}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\DUrole{hole}{intropattern\_list}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern}]{\sphinxcrossref{\DUrole{hole}{intropattern}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern}]{\sphinxcrossref{\DUrole{hole}{intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{*}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{**}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern_closed}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern\_closed}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{language/core/basic:grammar-token-term0}]{\sphinxcrossref{\DUrole{hole}{term0}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-simple_intropattern_closed}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern_closed}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern\_closed}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-rewriting_intropattern}]{\sphinxcrossref{\DUrole{hole}{rewriting\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{?}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\DUrole{hole}{intropattern\_list}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\&}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-rewriting_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-rewriting_intropattern}]{\sphinxcrossref{\DUrole{hole}{rewriting\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\sphinxhyphen{}>}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{<\sphinxhyphen{}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[}= {\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\DUrole{hole}{intropattern\_list}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ident}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Note that the intro pattern syntax varies between tactics.
Most tactics use \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}} in the grammar.
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.edestruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{edestruct}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}},
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.einduction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{einduction}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.ecase}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ecase}}}}} and the various
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} tactics use \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}, while
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eintros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eintros}}}}} use \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\DUrole{hole}{intropattern\_list}}}}}}}.
The \sphinxcode{\sphinxupquote{\DUrole{notation}{eqn:}}} construct in various tactics uses \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}}}.

\sphinxAtStartPar
\sphinxstylestrong{Naming patterns}

\sphinxAtStartPar
Use these elementary patterns to specify a name:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} — use the specified name

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{?}}} — let Coq choose a name

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} — generate a name that begins with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\_}}} — discard the matched part (unless it is required for another
hypothesis)

\item {} 
\sphinxAtStartPar
if a disjunction pattern omits a name, such as \sphinxcode{\sphinxupquote{\DUrole{operator}{{[}|}\DUrole{name}{H2}\DUrole{operator}{{]}}}}, Coq will choose a name

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Splitting patterns}

\sphinxAtStartPar
The most common splitting patterns are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
split a hypothesis in the form \sphinxcode{\sphinxupquote{\DUrole{notation}{A /\textbackslash{} B}}} into two
hypotheses \sphinxcode{\sphinxupquote{\DUrole{name}{H1}\DUrole{operator}{:} \DUrole{name}{A}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{H2}\DUrole{operator}{:} \DUrole{name}{B}}} using the pattern \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{H1} \DUrole{operator}{\&} \DUrole{name}{H2}\DUrole{operator}{)}}} or
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{H1}\DUrole{operator}{,} \DUrole{name}{H2}\DUrole{operator}{)}}} or \sphinxcode{\sphinxupquote{\DUrole{operator}{{[}}\DUrole{name}{H1} \DUrole{name}{H2}\DUrole{operator}{{]}}}}.
{\hyperref[\detokenize{proof-engine/tactics:intropattern-conj-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.  This also works on \sphinxcode{\sphinxupquote{\DUrole{notation}{A <\sphinxhyphen{}> B}}}, which
is just a notation representing \sphinxcode{\sphinxupquote{\DUrole{notation}{(A \sphinxhyphen{}> B) /\textbackslash{} (B \sphinxhyphen{}> A)}}}.

\item {} 
\sphinxAtStartPar
split a hypothesis in the form \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{\textbackslash{}/} \DUrole{name}{B}}} into two
subgoals using the pattern \sphinxcode{\sphinxupquote{\DUrole{operator}{{[}}\DUrole{name}{H1}\DUrole{operator}{|}\DUrole{name}{H2}\DUrole{operator}{{]}}}}.  The first subgoal will have the hypothesis
\sphinxcode{\sphinxupquote{\DUrole{name}{H1}\DUrole{operator}{:} \DUrole{name}{A}}} and the second subgoal will have the hypothesis \sphinxcode{\sphinxupquote{\DUrole{name}{H2}\DUrole{operator}{:} \DUrole{name}{B}}}.
{\hyperref[\detokenize{proof-engine/tactics:intropattern-disj-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}

\item {} 
\sphinxAtStartPar
split a hypothesis in either of the forms \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{B}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{\textbackslash{}/} \DUrole{name}{B}}} using the pattern \sphinxcode{\sphinxupquote{\DUrole{name,builtin,pseudo}{{[}{]}}}}.

\end{itemize}

\sphinxAtStartPar
Patterns can be nested: \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}{[}Ha|Hb{]} H{]}}}} can be used to split \sphinxcode{\sphinxupquote{\DUrole{notation}{(A \textbackslash{}/ B) /\textbackslash{} C}}}.

\sphinxAtStartPar
Note that there is no equivalent to intro patterns for goals.  For a goal \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{B}}},
use the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.split}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{split}}}}} tactic to replace the current goal with subgoals \sphinxcode{\sphinxupquote{\DUrole{name}{A}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{B}}}.
For a goal \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{\textbackslash{}/} \DUrole{name}{B}}}, use {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.left}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{left}}}}} to replace the current goal with \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}, or
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.right}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{right}}}}} to replace the current goal with \sphinxcode{\sphinxupquote{\DUrole{name}{B}}}.
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}} ) — matches
a product over an inductive type with a
{\hyperref[\detokenize{proof-engine/tactics:intropattern-cons-note}]{\sphinxcrossref{\DUrole{std,std-ref}{single constructor}}}}.
If the number of patterns
equals the number of constructor arguments, then it applies the patterns only to
the arguments, and
\sphinxcode{\sphinxupquote{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}{]}}}}.
If the number of patterns equals the number of constructor arguments plus the number
of \sphinxcode{\sphinxupquote{\DUrole{notation}{let\sphinxhyphen{}ins}}}, the patterns are applied to the arguments and \sphinxcode{\sphinxupquote{\DUrole{notation}{let\sphinxhyphen{}in}}} variables.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\&}} )}}} — matches a right\sphinxhyphen{}hand nested term that consists
of one or more nested binary inductive types such as \sphinxcode{\sphinxupquote{\DUrole{name}{a1} \DUrole{name}{OP1} \DUrole{name}{a2} \DUrole{name}{OP2} \DUrole{operator}{...}}}
(where the \sphinxcode{\sphinxupquote{\DUrole{name}{OPn}}} are right\sphinxhyphen{}associative).
(If the \sphinxcode{\sphinxupquote{\DUrole{name}{OPn}}} are left\sphinxhyphen{}associative, additional parentheses will be needed to make the
term right\sphinxhyphen{}hand nested, such as \sphinxcode{\sphinxupquote{\DUrole{name}{a1} \DUrole{name}{OP1} \DUrole{operator}{(}\DUrole{name}{a2} \DUrole{name}{OP2} \DUrole{operator}{...)}}}.)
The splitting pattern can have more than 2 names, for example \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{H1} \DUrole{operator}{\&} \DUrole{name}{H2} \DUrole{operator}{\&} \DUrole{name}{H3}\DUrole{operator}{)}}}
matches \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{B} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{C}}}.
The inductive types must have a
{\hyperref[\detokenize{proof-engine/tactics:intropattern-cons-note}]{\sphinxcrossref{\DUrole{std,std-ref}{single constructor with two parameters}}}}.
{\hyperref[\detokenize{proof-engine/tactics:intropattern-ampersand-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\DUrole{hole}{intropattern\_list}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} {]}}}} — splits an inductive type that has
{\hyperref[\detokenize{proof-engine/tactics:intropattern-cons-note}]{\sphinxcrossref{\DUrole{std,std-ref}{multiple constructors}}}}
such as \sphinxcode{\sphinxupquote{\DUrole{notation}{A \textbackslash{}/ B}}}
into multiple subgoals.  The number of {\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intropattern\_list}}}}} must be the same as the number of
constructors for the matched part.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern}]{\sphinxcrossref{\DUrole{hole}{intropattern}}}}}\DUrole{notation-sup}{+}} {]}}}} — splits an inductive type that has a
{\hyperref[\detokenize{proof-engine/tactics:intropattern-cons-note}]{\sphinxcrossref{\DUrole{std,std-ref}{single constructor with multiple parameters}}}}
such as \sphinxcode{\sphinxupquote{\DUrole{notation}{A /\textbackslash{} B}}} into multiple hypotheses.  Use \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}H1 {[}H2 H3{]}{]}}}} to match \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{B} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{C}}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}{]}}}} — splits an inductive type:  If the inductive
type has multiple constructors, such as \sphinxcode{\sphinxupquote{\DUrole{notation}{A \textbackslash{}/ B}}},
create one subgoal for each constructor.  If the inductive type has a single constructor with
multiple parameters, such as \sphinxcode{\sphinxupquote{\DUrole{notation}{A /\textbackslash{} B}}}, split it into multiple hypotheses.

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Equality patterns}

\sphinxAtStartPar
These patterns can be used when the hypothesis is an equality:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}>}}} — replaces the right\sphinxhyphen{}hand side of the hypothesis with the left\sphinxhyphen{}hand
side of the hypothesis in the conclusion of the goal; the hypothesis is
cleared; if the left\sphinxhyphen{}hand side of the hypothesis is a variable, it is
substituted everywhere in the context and the variable is removed.
{\hyperref[\detokenize{proof-engine/tactics:intropattern-rarrow-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{<\sphinxhyphen{}}}} — similar to \sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}>}}}, but replaces the left\sphinxhyphen{}hand side of the hypothesis
with the right\sphinxhyphen{}hand side of the hypothesis.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}= \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern}]{\sphinxcrossref{\DUrole{hole}{intropattern}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} {]}}}} — If the product is over an equality type,
applies either {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}}.
If {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} is applicable, the intropattern
is used on the hypotheses generated by {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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.
{\hyperref[\detokenize{proof-engine/tactics:intropattern-inj-discr-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Other patterns}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{*}}} — introduces one or more quantified variables from the result
until there are no more quantified variables.
{\hyperref[\detokenize{proof-engine/tactics:intropattern-star-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{**}}} — introduces one or more quantified variables or hypotheses from the result until there are
no more quantified variables or implications (\sphinxcode{\sphinxupquote{\DUrole{operator}{\sphinxhyphen{}>}}}).  \sphinxcode{\sphinxupquote{\DUrole{keyword}{intros} \DUrole{operator}{**}}} is equivalent
to \sphinxcode{\sphinxupquote{\DUrole{keyword}{intros}}}.
{\hyperref[\detokenize{proof-engine/tactics:intropattern-2stars-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern_closed}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern\_closed}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\% {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}}}} — first applies each of the terms
with the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-_u2026-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply … in}}}}} tactic on the hypothesis to be introduced, then it uses
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern_closed}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern\_closed}}}}}}}.
{\hyperref[\detokenize{proof-engine/tactics:intropattern-injection-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}

\end{itemize}
\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-cons-note}}
\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{A \textbackslash{}/ B}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{A /\textbackslash{} B}}} use infix notation to refer to the inductive
types \sphinxcode{\sphinxupquote{\DUrole{notation}{or}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{and}}}.
\sphinxcode{\sphinxupquote{\DUrole{notation}{or}}} has multiple constructors (\sphinxcode{\sphinxupquote{\DUrole{notation}{or\_introl}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{or\_intror}}}),
while \sphinxcode{\sphinxupquote{\DUrole{notation}{and}}} has a single constructor (\sphinxcode{\sphinxupquote{\DUrole{notation}{conj}}}) with multiple parameters
(\sphinxcode{\sphinxupquote{\DUrole{notation}{A}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{B}}}).
These are defined in \sphinxcode{\sphinxupquote{theories/Init/Logic.v}}.  The "where" clauses define the
infix notation for "or" and "and".

\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{o}{|} \PYG{n}{or\PYGZus{}introl} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{B}
  \PYG{o}{|} \PYG{n}{or\PYGZus{}intror} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{B}
\PYG{n}{where} \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}{type\PYGZus{}scope}\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{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B}
\PYG{n}{where} \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}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros \DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}}}}} is not always equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{intros p; ... ; intros p}}}
if some of the \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}} are \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}.  In the first form, all erasures are done
at once, while they're done sequentially for each tactic in the second form.
If the second matched term depends on the first matched term and the pattern
for both is \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}} (i.e., both will be erased), the first \sphinxcode{\sphinxupquote{\DUrole{notation}{intros}}} in the second
form will fail because the second matched term still has the dependency on the first.
\end{sphinxadmonition}

\sphinxAtStartPar
Examples:

\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-conj-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: intro pattern for /\textbackslash{}}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \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}{True}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{destruct} \PYG{n}{H} \PYG{k}{as} \PYG{o}{(}\PYG{n}{HA} \PYG{o}{\PYGZam{}} \PYG{n}{HB}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \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}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-disj-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: intro pattern for \textbackslash{}/}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \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}{True}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{destruct} \PYG{n}{H} \PYG{k}{as} \PYG{o}{[}\PYG{n}{HA}\PYG{o}{|}\PYG{n}{HB}\PYG{o}{]}\PYG{o}{.} \PYG{n}{all}\PYG{o}{:} \PYG{n}{swap} \PYG{l+m+mi}{1} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{HA} \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}{True}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \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}{True}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-rarrow-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: \sphinxhyphen{}> intro pattern}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{y} \PYG{o}{=} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{H} \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}{z}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-inj-discr-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: {[}={]} intro pattern}

\sphinxAtStartPar
The first \sphinxcode{\sphinxupquote{\DUrole{notation}{intros {[}={]}}}} uses {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} to strip \sphinxcode{\sphinxupquote{\DUrole{notation}{(S ...)}}} from
both sides of the matched equality.  The second uses {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}} on
the contradiction \sphinxcode{\sphinxupquote{\DUrole{notation}{1 = 2}}} (internally represented as \sphinxcode{\sphinxupquote{\DUrole{notation}{(S O) = (S (S O))}}})
to complete the goal.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{S} \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{o}{[}\PYG{o}{=} \PYG{n}{H}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{H} \PYG{o}{:} \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{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{o}{[}\PYG{o}{=}\PYG{o}{]}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-ampersand-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: (A \& B \& ...) intro pattern}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k}{exists} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{B} \PYG{n}{x} \PYG{o}{/\PYGZbs{}} \PYG{n}{C}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\PYGZam{}} \PYG{n}{x} \PYG{o}{\PYGZam{}} \PYG{n}{b} \PYG{o}{\PYGZam{}} \PYG{n}{c}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{b} \PYG{o}{:} \PYG{n}{B} \PYG{n}{x}
      \PYG{n}{c} \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}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-star-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: * intro pattern}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{o}{*}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \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}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-2stars-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: ** pattern ("intros **" is equivalent to "intros")}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{o}{*}\PYG{o}{*}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \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}{B}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: compound intro pattern}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{o}{*} \PYG{o}{[}\PYG{n}{a} \PYG{o}{|} \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}{goals}
      
      \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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{C}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{swap} \PYG{l+m+mi}{1} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B}\PYG{o}{,} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{c} \PYG{o}{:} \PYG{n}{C}
      \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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{C}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/tactics:intropattern-injection-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: combined intro pattern using {[}={]} \sphinxhyphen{}> and \%}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{xs}\PYG{o}{,} \PYG{n}{ys} \PYG{o}{:} \PYG{n}{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}{S} \PYG{o}{(}\PYG{n}{length} \PYG{n}{ys}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{xs} \PYG{o}{+}\PYG{o}{+} \PYG{n}{ys} \PYG{o}{=} \PYG{n}{xs}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{o}{[}\PYG{o}{=}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{o}{\PYGZpc{}}\PYG{n}{length\PYGZus{}zero\PYGZus{}iff\PYGZus{}nil}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{xs} \PYG{o}{:} \PYG{n}{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}{xs} \PYG{o}{+}\PYG{o}{+} \PYG{n}{nil} \PYG{o}{=} \PYG{n}{xs}
\end{sphinxVerbatim}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{intros}} would add \sphinxcode{\sphinxupquote{\DUrole{name}{H} \DUrole{operator}{:} \DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{length} \DUrole{name}{ys}\DUrole{operator}{)} \DUrole{operator}{=} \DUrole{literal,number,integer}{1}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{intros {[}={]}}} would additionally apply {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} to \sphinxcode{\sphinxupquote{\DUrole{name}{H}}} to yield \sphinxcode{\sphinxupquote{\DUrole{name}{H0} \DUrole{operator}{:} \DUrole{name}{length} \DUrole{name}{ys} \DUrole{operator}{=} \DUrole{literal,number,integer}{0}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{intros {[}=\sphinxhyphen{}>\%length\_zero\_iff\_nil{]}}} applies the theorem, making H the equality \sphinxcode{\sphinxupquote{\DUrole{name}{l}\DUrole{operator}{=}\DUrole{name}{nil}}},
which is then applied as for \sphinxcode{\sphinxupquote{\DUrole{operator}{\sphinxhyphen{}>}}}.

\end{itemize}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Theorem} \PYG{n}{length\PYGZus{}zero\PYGZus{}iff\PYGZus{}nil} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}\PYG{o}{)}\PYG{o}{:}
   \PYG{n}{length} \PYG{n}{l} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{l}\PYG{o}{=}\PYG{n}{nil}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The example is based on \sphinxhref{https://github.com/tchajed/coq-tricks/blob/8e6efe4971ed828ac8bdb5512c1f615d7d62691e/src/IntroPatterns.v}{Tej Chajed's coq\sphinxhyphen{}tricks}%
\begin{footnote}[27]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/tchajed/coq-tricks/blob/8e6efe4971ed828ac8bdb5512c1f615d7d62691e/src/IntroPatterns.v}
%
\end{footnote}
\end{sphinxadmonition}
\end{quote}


\paragraph{Occurrence clauses}
\label{\detokenize{proof-engine/tactics:occurrence-clauses}}\label{\detokenize{proof-engine/tactics:occurrencessets}}
\sphinxAtStartPar
An \DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/tactics:term-occurrence}}occurrence} is a subterm of a goal or hypothesis that
matches a pattern provided by a tactic.  Occurrence clauses
select a subset of the ocurrences in a goal and/or in
one or more of its hypotheses.
\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-occurrences}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-occs_nums}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-nat_or_var}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-hyp_occs}]{\sphinxcrossref{\DUrole{hole}{hyp\_occs}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} \DUrole{repeat-wrapper}{\DUrole{repeat}{|\sphinxhyphen{} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{* |\sphinxhyphen{} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{|\sphinxhyphen{} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-hyp_occs}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-hyp_occs}]{\sphinxcrossref{\DUrole{hole}{hyp\_occs}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-hypident}]{\sphinxcrossref{\DUrole{hole}{hypident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-hypident}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-hypident}]{\sphinxcrossref{\DUrole{hole}{hypident}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( type of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( value of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-concl_occs}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{* \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
The first form of {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occurrences}}}}} selects occurrences in
the conclusion of the goal.  The second form can select occurrences
in the goal conclusion and in one or more hypotheses.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
A semantically restricted form of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}} that doesn't allow the
\sphinxcode{\sphinxupquote{at}} clause anywhere within it.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{+}}}}}}] \leavevmode
\sphinxAtStartPar
Selects the specified occurrences within a single goal or hypothesis.
Occurrences are numbered starting with 1 following a depth\sphinxhyphen{}first traversal
of the term's expression, including occurrences in
{\hyperref[\detokenize{language/extensions/implicit-arguments:implicitarguments}]{\sphinxcrossref{\DUrole{std,std-ref}{implicit arguments}}}}
and {\hyperref[\detokenize{addendum/implicit-coercions:coercions}]{\sphinxcrossref{\DUrole{std,std-ref}{coercions}}}} that are not displayed by default.
(Set the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} flag to show those in the printed term.)

\sphinxAtStartPar
For example, when matching the pattern \sphinxcode{\sphinxupquote{\_ + \_}} in the term \sphinxcode{\sphinxupquote{(a + b) + c}},
occurrence 1 is \sphinxcode{\sphinxupquote{(...) + c}} and
occurrence 2 is \sphinxcode{\sphinxupquote{(a + b)}}.  When matching that pattern with term \sphinxcode{\sphinxupquote{a + (b + c)}},
occurrence 1 is \sphinxcode{\sphinxupquote{a + (...)}} and occurrence 2 is \sphinxcode{\sphinxupquote{b + c}}.

\sphinxAtStartPar
Specifying \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} includes all occurrences \sphinxstyleemphasis{except} the ones listed.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-hyp_occs}]{\sphinxcrossref{\DUrole{hole}{hyp\_occs}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} \DUrole{repeat-wrapper}{\DUrole{repeat}{|\sphinxhyphen{} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Selects occurrences in the specified hypotheses and the
specified occurrences in the conclusion.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{* |\sphinxhyphen{} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Selects all occurrences in all hypotheses and the
specified occurrences in the conclusion.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{|\sphinxhyphen{} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Selects the specified occurrences in the conclusion.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}} ::= \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Selects all occurrences in all hypotheses and in the specified occurrences
in the conclusion.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-hypident}]{\sphinxcrossref{\DUrole{hole}{hypident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Omiting {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occs\_nums}}}}} selects all occurrences within the hypothesis.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-hypident}]{\sphinxcrossref{\DUrole{hole}{hypident}}}} ::= {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
Selects the hypothesis named {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{( type of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} )}}}}] \leavevmode
\sphinxAtStartPar
Selects the type part of the named hypothesis (e.g. \sphinxcode{\sphinxupquote{: nat}}).

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{( value of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} )}}}}] \leavevmode
\sphinxAtStartPar
Selects the value part of the named hypothesis (e.g. \sphinxcode{\sphinxupquote{:= 1}}).

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-concl_occs}]{\sphinxcrossref{\DUrole{hole}{concl\_occs}}}} ::= * \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Selects occurrences in the conclusion.  '*' by itself selects all occurrences.
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}}} selects the specified occurrences.

\end{description}

\sphinxAtStartPar
Use \sphinxcode{\sphinxupquote{in *}} to select all occurrences in all hypotheses and the conclusion,
which is equivalent to \sphinxcode{\sphinxupquote{in * |\sphinxhyphen{} *}}.  Use \sphinxcode{\sphinxupquote{* |\sphinxhyphen{}}} to select all occurrences
in all hypotheses.

\sphinxAtStartPar
Tactics that select a specific hypothesis H to apply to other hypotheses,
such as {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} \sphinxcode{\sphinxupquote{H in * |\sphinxhyphen{}}}, won't apply H to itself.

\sphinxAtStartPar
If multiple
occurrences are given, such as in {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} \sphinxcode{\sphinxupquote{H at 1 2 3}}, the tactic
must match at least one occurrence in order to succeed.  The tactic will fail
if no occurrences match.  Occurrence numbers that are out of range (e.g.
\sphinxcode{\sphinxupquote{at 1 3}} when there are only 2 occurrences in the hypothesis or conclusion)
are ignored.

\sphinxAtStartPar
Tactics that use occurrence clauses include {\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{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}.
\end{quote}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:managingthelocalcontext}]{\sphinxcrossref{\DUrole{std,std-ref}{Managing the local context}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:caseanalysisandinduction}]{\sphinxcrossref{\DUrole{std,std-ref}{Case analysis and induction}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:printing-constructions-full}]{\sphinxcrossref{\DUrole{std,std-ref}{Printing constructions in full}}}}.




\subsubsection{Applying theorems}
\label{\detokenize{proof-engine/tactics:applying-theorems}}\label{\detokenize{proof-engine/tactics:applyingtheorems}}\index{exact (tactic)@\spxentry{exact}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.exact}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exact~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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/core/conversion:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}}).
\index{Not an exact proof (error)@\spxentry{Not an exact proof}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{eexact (tactic variant)@\spxentry{eexact}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
\sphinxAtStartPar
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{savenotes}


\end{fulllineitems}\end{savenotes}

\index{assumption (tactic)@\spxentry{assumption}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.assumption}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assumption}}}}
\sphinxAtStartPar
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 (error)@\spxentry{No such assumption}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{eassumption (tactic variant)@\spxentry{eassumption}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eassumption}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eassumption}}}}
\sphinxAtStartPar
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{savenotes}


\end{fulllineitems}\end{savenotes}

\index{refine (tactic)@\spxentry{refine}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.refine}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{refine~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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/core/basic: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 remaining holes in the elaborated term. The type
of holes must be either synthesized by the system or declared by an explicit cast
like \sphinxcode{\sphinxupquote{(\_ : nat \sphinxhyphen{}> Prop)}}. Any subgoal that
occurs in other subgoals is automatically shelved, as if calling
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.shelve_unifiable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{shelve\_unifiable}}}}}. The produced subgoals (shelved or not)
are \sphinxstyleemphasis{not} candidates for typeclass resolution, even if they have a type\sphinxhyphen{}class
type as conclusion, letting the user control when and how typeclass resolution
is launched on them. This low\sphinxhyphen{}level tactic can be useful to advanced users.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Option} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{Fail} \PYG{o}{:} \PYG{n}{Option}
\PYG{o}{|} \PYG{n}{Ok} \PYG{o}{:} \PYG{n}{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{n}{Option\PYGZus{}sind} \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{n}{bool}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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{n}{bool} \PYG{k}{with}
      \PYG{o}{|} \PYG{n}{Fail} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZus{}}
      \PYG{o}{|} \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}{goal}
      
      \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{n}{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}{goals}\PYG{o}{.}

\PYG{k+kn}{Defined}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Invalid argument (error)@\spxentry{Invalid argument}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.Invalid-argument}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Invalid~argument.}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{Refine passed ill\sphinxhyphen{}formed term (error)@\spxentry{Refine passed ill\sphinxhyphen{}formed term}\spxextra{error}}

\begin{savenotes}\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\sphinxhyphen{}formed~term.}}}}
\sphinxAtStartPar
The term you gave is not a valid proof (not easy to debug in general). This
message may also occur in higher\sphinxhyphen{}level tactics that call {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}
internally.

\end{fulllineitems}\end{savenotes}

\index{Cannot infer a term for this placeholder. (refine) (error)@\spxentry{Cannot infer a term for this placeholder. (refine)}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
There is a hole in the term you gave whose type cannot be inferred. Put a
cast around it.

\end{fulllineitems}\end{savenotes}

\index{simple refine (tactic variant)@\spxentry{simple refine}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic behaves like refine, but it does not shelve any subgoal. It does
not perform any beta\sphinxhyphen{}reduction either.

\end{fulllineitems}\end{savenotes}

\index{notypeclasses refine (tactic variant)@\spxentry{notypeclasses refine}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{simple notypeclasses refine (tactic variant)@\spxentry{simple notypeclasses refine}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic behaves like the combination of {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple refine}}}}} and
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.notypeclasses-refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{notypeclasses refine}}}}}: it performs type checking without resolution of
typeclasses, does not perform beta reductions or shelve the subgoals.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Debug}}}}} \sphinxcode{\sphinxupquote{"unification"}} enables printing traces of
unification steps used during elaboration/typechecking and the
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic. \sphinxcode{\sphinxupquote{"ho\sphinxhyphen{}unification"}} prints information
about higher order heuristics.

\end{fulllineitems}\end{savenotes}

\index{apply (tactic)@\spxentry{apply}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.apply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic applies to any goal. The argument term is a term well\sphinxhyphen{}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/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. If it succeeds, then
the tactic returns as many subgoals as the number of non\sphinxhyphen{}dependent premises
of the type of term. If the conclusion of the type of {\hyperref[\detokenize{language/core/basic: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\sphinxhyphen{}to\sphinxhyphen{}right order.

\sphinxAtStartPar
The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} relies on first\sphinxhyphen{}order unification with dependent
types unless the conclusion of the type of {\hyperref[\detokenize{language/core/basic: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 => 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}{=>} \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{proofs/writing-proofs/equality:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} to transform the goal so that it
gets the form \sphinxcode{\sphinxupquote{\DUrole{notation}{(fun x => Q) u$_{\text{1}}$ ... u$_{\text{n}}$}}}.
\index{Unable to unify ‘term’ with ‘term’ (error)@\spxentry{Unable to unify ‘term’ with ‘term’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.Unable-to-unify-_u2018term_u2019-with-_u2018term_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~unify~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
\sphinxAtStartPar
The {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} tactic failed to match the conclusion of {\hyperref[\detokenize{language/core/basic: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{proofs/writing-proofs/equality:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}
tactics.

\end{fulllineitems}\end{savenotes}

\index{Unable to find an instance for the variables ‘ident’…‘ident’ (error)@\spxentry{Unable to find an instance for the variables ‘ident’…‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.Unable-to-find-an-instance-for-the-variables-_u2018ident_u2019_u2026_u2018ident_u2019}}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}.}}}}
\sphinxAtStartPar
This occurs when some instantiations of the premises of {\hyperref[\detokenize{language/core/basic: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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
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/core/basic: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 (error)@\spxentry{Not the right number of missing arguments}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id4}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~the~right~number~of~missing~arguments.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
This also provides apply with values for instantiating premises. Here, variables
are referred by names and non\sphinxhyphen{}dependent products by increasing numbers (see
{\hyperref[\detokenize{proof-engine/tactics:bindings}]{\sphinxcrossref{\DUrole{std,std-ref}{Bindings}}}}).

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This is a shortcut for \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}; {[}.. | ... ; {[} .. | apply {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{n}}$}}}}{]} ... {]}}}},
i.e. for the successive applications of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}$_{\text{i+1}}$ on the last subgoal
generated by \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{i}}$}}}}}}} , starting from the application of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{eapply (tactic variant)@\spxentry{eapply}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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/extensions/evars:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}). The instantiation is
intended to be found later in the proof.

\end{fulllineitems}\end{savenotes}

\index{rapply (tactic variant)@\spxentry{rapply}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.rapply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rapply~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.rapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rapply}}}}} behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}} but it
uses the proof engine of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} for dealing with
existential variables, holes, and conversion problems.  This may
result in slightly different behavior regarding which conversion
problems are solvable.  However, like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} but unlike
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.rapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rapply}}}}} will fail if there are any holes
which remain in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} itself after typechecking and
typeclass resolution but before unification with the goal.  More
technically, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is first parsed as a
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-constr}}\sphinxcode{\sphinxupquote{constr}}} rather than as a \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-uconstr}}\sphinxcode{\sphinxupquote{uconstr}}} or
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-open_constr}}\sphinxcode{\sphinxupquote{open\_constr}}} before being applied to the goal. Note
that {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.rapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rapply}}}}} prefers to instantiate as many hypotheses of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} as possible.  As a result, if it is possible to apply
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to arbitrarily many arguments without getting a type
error, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.rapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rapply}}}}} will loop.

\sphinxAtStartPar
Note that you need to \sphinxcode{\sphinxupquote{\DUrole{notation}{Require Import Coq.Program.Tactics}}} to
make use of {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.rapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rapply}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~apply~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
\sphinxAtStartPar
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}}}.

\phantomsection\label{\detokenize{proof-engine/tactics:simple-apply-ex}}
\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{id} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{id} \PYG{n}{x} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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 = ?M161}\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}

\sphinxAtStartPar
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\sphinxhyphen{}suited for uses in user\sphinxhyphen{}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}\end{savenotes}

\index{simple apply (tactic variant)@\spxentry{simple apply}\spxextra{tactic variant}}\index{simple eapply (tactic variant)@\spxentry{simple eapply}\spxextra{tactic variant}}

\begin{savenotes}\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-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\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-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{lapply (tactic variant)@\spxentry{lapply}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic applies to any goal, say \sphinxcode{\sphinxupquote{\DUrole{name}{G}}}. The argument term has to be
well\sphinxhyphen{}formed in the current context, its type being reducible to a non\sphinxhyphen{}dependent
product \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{B}}} with \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} possibly containing products. Then it generates
two subgoals \sphinxcode{\sphinxupquote{\DUrole{name}{B}\DUrole{operator}{\sphinxhyphen{}>}\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}{\sphinxhyphen{}>}\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 (warning)@\spxentry{When ‘term’ contains more than one non dependent product the tactic lapply only takes into account the first product}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:warn.When-_u2018term_u2019-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/core/basic: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{savenotes}


\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Assume we have a transitive relation \sphinxcode{\sphinxupquote{R}} on \sphinxcode{\sphinxupquote{nat}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{R} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{Rtrans} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{:}\PYG{n}{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}{Parameters} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{Rnm} \PYG{o}{:} \PYG{n}{R} \PYG{n}{n} \PYG{n}{m}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{Rmp} \PYG{o}{:} \PYG{n}{R} \PYG{n}{m} \PYG{n}{p}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Consider the goal \sphinxcode{\sphinxupquote{(R n p)}} provable using the transitivity of \sphinxcode{\sphinxupquote{R}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{R} \PYG{n}{n} \PYG{n}{p}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{n}{Rtrans}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{6}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{12}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{apply} \PYG{n}{Rtrans}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}       \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\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}

\sphinxAtStartPar
A solution is to \sphinxcode{\sphinxupquote{apply (Rtrans n m p)}} or \sphinxcode{\sphinxupquote{(Rtrans n m)}}.

\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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{R} \PYG{n}{m} \PYG{n}{p}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that \sphinxcode{\sphinxupquote{n}} can be inferred from the goal, so the following would work
too.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{o}{(}\PYG{n}{Rtrans} \PYG{o}{\PYGZus{}} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
More elegantly, \sphinxcode{\sphinxupquote{apply Rtrans with (y:=m)}} allows only mentioning the
unknown m:

\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}

\sphinxAtStartPar
Another solution is to mention the proof of \sphinxcode{\sphinxupquote{(R x y)}} in \sphinxcode{\sphinxupquote{Rtrans}}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\sphinxAtStartPar
... or the proof of \sphinxcode{\sphinxupquote{(R y z)}}.

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{eapply} \PYG{n}{Rtrans}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{focused} \PYG{n}{goals}
    \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}{goal} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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, ... \sphinxhyphen{}> A}}. Excluding this kind of lemma can be avoided by
setting the following flag:
\end{sphinxadmonition}
\index{Universal Lemma Under Conjunction (flag)@\spxentry{Universal Lemma Under Conjunction}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}, which preserves compatibility with versions of Coq prior to
8.4 is also available for \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-_u2026-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply … in}}}}}).

\end{fulllineitems}\end{savenotes}

\index{apply … in (tactic)@\spxentry{apply … in}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.apply-_u2026-in}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This tactic applies to any goal. The argument {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is a term
well\sphinxhyphen{}formed in the local context and the argument {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is an
hypothesis of the context.
The tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} tries to match the conclusion of the
type of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} against a non\sphinxhyphen{}dependent premise of the type
of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, trying them from right to left. If it succeeds, the
statement of hypothesis {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is replaced by the conclusion of
the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. The tactic also returns as many subgoals as the
number of other non\sphinxhyphen{}dependent premises in the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and of
the non\sphinxhyphen{}dependent premises of the type of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. If the conclusion
of the type of {\hyperref[\detokenize{language/core/basic: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\sphinxhyphen{}dependent premise matches the conclusion of the type of
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. Tuples are decomposed in a width\sphinxhyphen{}first left\sphinxhyphen{}to\sphinxhyphen{}right order
(for instance if the type of \sphinxcode{\sphinxupquote{\DUrole{name}{H1}}} is \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{<\sphinxhyphen{}>} \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\sphinxhyphen{}order pattern matching
with dependent types.
\index{Statement without assumptions (error)@\spxentry{Statement without assumptions}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
This happens if the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} has no non\sphinxhyphen{}dependent premise.

\end{fulllineitems}\end{savenotes}

\index{Unable to apply (error)@\spxentry{Unable to apply}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
This happens if the conclusion of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} does not match any of
the non\sphinxhyphen{}dependent premises of the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This applies each {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} in sequence in each hypothesis {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This does the same but uses the bindings to instantiate
parameters of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} (see {\hyperref[\detokenize{proof-engine/tactics:bindings}]{\sphinxcrossref{\DUrole{std,std-ref}{Bindings}}}}).

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eapply~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This works as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-_u2026-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply … in}}}}} but turns unresolved bindings into
existential variables, if any, instead of failing.

\end{fulllineitems}\end{savenotes}

\index{apply … in … as (tactic variant)@\spxentry{apply … in … as}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.apply-_u2026-in-_u2026-as}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This works as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-_u2026-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply … in}}}}} but applying an associated
{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_intropattern}}}}} to each hypothesis {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
that comes with such clause.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~apply~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-_u2026-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply … in}}}}} but it reasons modulo conversion
only on subterms that contain no variables to instantiate and does not
traverse tuples. See {\hyperref[\detokenize{proof-engine/tactics:simple-apply-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{the corresponding example}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\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-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{simple}\DUrole{notation-sup}{?}}~eapply~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This summarizes the different syntactic variants of \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{eapply {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Debug}}}}} \sphinxcode{\sphinxupquote{"tactic\sphinxhyphen{}unification"}} enables printing traces of
unification steps in tactic unification. Tactic unification is used in
tactics such as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}.


\subsubsection{Managing the local context}
\label{\detokenize{proof-engine/tactics:managing-the-local-context}}\label{\detokenize{proof-engine/tactics:managingthelocalcontext}}\index{intro (tactic)@\spxentry{intro}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.intro}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro}}}}
\sphinxAtStartPar
This tactic applies to a goal that is either a product or starts with a
let\sphinxhyphen{}binder. If the goal is a product, the tactic implements the "Lam" rule
given in {\hyperref[\detokenize{language/cic:id4}]{\sphinxcrossref{\DUrole{std,std-ref}{Typing rules}}}} \sphinxstepexplicit %
\begin{footnote}[1]\phantomsection\label{\thesphinxscope.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\sphinxhyphen{}binder,
then the tactic implements a mix of the "Let" and "Conv".

\sphinxAtStartPar
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}}}.

\sphinxAtStartPar
If the goal is a non\sphinxhyphen{}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}}}.

\sphinxAtStartPar
If the goal is an existential variable, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} forces the resolution
of the existential variable into a dependent product \(\forall\) \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:?}\DUrole{name}{X}\DUrole{operator}{,} \DUrole{operator}{?}\DUrole{name}{Y}}},
puts \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:?}\DUrole{name}{X}}} in the local context and leaves \sphinxcode{\sphinxupquote{\DUrole{operator}{?}\DUrole{name}{Y}}} as a new subgoal
allowed to depend on \sphinxcode{\sphinxupquote{\DUrole{name}{x}}}.

\sphinxAtStartPar
The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} applies the tactic {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}}
until {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} can be applied or the goal is not head\sphinxhyphen{}reducible.
\index{No product even after head\sphinxhyphen{}reduction (error)@\spxentry{No product even after head\sphinxhyphen{}reduction}\spxextra{error}}

\begin{savenotes}\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\sphinxhyphen{}reduction.}}}}
\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This applies {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} but forces {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} to be the name of
the introduced hypothesis.
\index{‘ident’ is already used (error)@\spxentry{‘ident’ is already used}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn._u2018ident_u2019-is-already-used}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~used.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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/core/modules:qualified-names}]{\sphinxcrossref{\DUrole{std,std-ref}{Qualified identifiers}}}}).
\end{sphinxadmonition}
\index{intros (tactic variant)@\spxentry{intros}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.intros}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros}}}}
\sphinxAtStartPar
This repeats {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} until it meets the head\sphinxhyphen{}constant. It never
reduces head\sphinxhyphen{}constants and it never fails.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}.}}}}
\sphinxAtStartPar
This is equivalent to the composed tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{intro {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; ... ; intro {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros~until~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This repeats intro until it meets a premise of the goal having the
form \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}} and discharges the variable
named {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} of the current goal.
\index{No such hypothesis in current goal (error)@\spxentry{No such hypothesis in current goal}\spxextra{error}}

\begin{savenotes}\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{savenotes}


\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros~until~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This repeats {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} until the {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}\sphinxhyphen{}th non\sphinxhyphen{}dependent
product.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
On the subgoal \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{operator}{:} \DUrole{name}{nat}\DUrole{operator}{,} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y} \DUrole{operator}{\sphinxhyphen{}>} \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}{\sphinxhyphen{}>} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{name}{x}}} is the first non\sphinxhyphen{}dependent product.

\sphinxAtStartPar
On the subgoal \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{name}{z} \DUrole{operator}{:} \DUrole{name}{nat}\DUrole{operator}{,} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y} \DUrole{operator}{\sphinxhyphen{}>} \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\sphinxhyphen{}dependent
product: \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{operator}{:} \DUrole{name}{nat}\DUrole{operator}{,} \DUrole{name}{nat} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{name}{x}}}.
\end{sphinxadmonition}
\index{No such hypothesis in current goal (error)@\spxentry{No such hypothesis in current goal}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id6}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis~in~current~goal.}}}}
\sphinxAtStartPar
This happens when {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} is 0 or is greater than the number of
non\sphinxhyphen{}dependent products of the goal.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}~after~{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}~before~{\hyperref[\detokenize{language/core/basic: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/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}~at~bottom}}}}
\sphinxAtStartPar
These tactics apply \sphinxcode{\sphinxupquote{\DUrole{notation}{intro \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}},
before the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic: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}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.move-_u2026-before-_u2026}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move … before …}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.move-_u2026-at-top}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move … at top}}}}},
or {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.move-_u2026-at-bottom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move … at bottom}}}}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
\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’ (error)@\spxentry{No such hypothesis: ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.No-such-hypothesis:-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis:~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{intros … (tactic)@\spxentry{intros …}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.intros-_u2026}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\DUrole{hole}{intropattern\_list}}}}}}}}
\sphinxAtStartPar
Introduces one or more variables or hypotheses from the goal by matching the
intro patterns.  See the description in {\hyperref[\detokenize{proof-engine/tactics:intropatterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Intro patterns}}}}.

\end{fulllineitems}\end{savenotes}

\index{eintros (tactic)@\spxentry{eintros}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.eintros}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eintros~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\DUrole{hole}{intropattern\_list}}}}}}}}
\sphinxAtStartPar
Works just like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intros-_u2026}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros …}}}}} except that it creates existential variables
for any unresolved variables rather than failing.

\end{fulllineitems}\end{savenotes}

\index{clear (tactic)@\spxentry{clear}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.clear}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This tactic erases the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is no more displayed and no
more usable in the proof development.
\index{No such hypothesis (error)@\spxentry{No such hypothesis}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{‘ident’ is used in the conclusion (error)@\spxentry{‘ident’ is used in the conclusion}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn._u2018ident_u2019-is-used-in-the-conclusion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~used~in~the~conclusion.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘ident’ is used in the hypothesis ‘ident’ (error)@\spxentry{‘ident’ is used in the hypothesis ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn._u2018ident_u2019-is-used-in-the-hypothesis-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~used~in~the~hypothesis~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{clear {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}. ... clear {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear~\sphinxhyphen{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} and in the goal.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear}}}}
\sphinxAtStartPar
This variants clears all the hypotheses except the ones the goal depends on.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear~dependent~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This clears the hypothesis {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} and all the hypotheses that
depend on it.

\end{fulllineitems}\end{savenotes}

\index{clearbody (tactic variant)@\spxentry{clearbody}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This tactic expects \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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 (error)@\spxentry{‘ident’ is not a local definition}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn._u2018ident_u2019-is-not-a-local-definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~not~a~local~definition.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{revert (tactic)@\spxentry{revert}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.revert}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{revert~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This applies to any goal with variables \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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 (error)@\spxentry{No such hypothesis}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id7}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘ident’ is used in the hypothesis ‘ident’ (error)@\spxentry{‘ident’ is used in the hypothesis ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id8}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~is~used~in~the~hypothesis~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{revert dependent (tactic variant)@\spxentry{revert dependent}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This moves to the goal the hypothesis {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} and all the
hypotheses that depend on it.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{move (tactic)@\spxentry{move}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.move}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~after~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}
\sphinxAtStartPar
This moves the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} in the local context after
the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} comes before \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} that
(possibly indirectly) depend on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the order of dependencies.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} comes after \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} that
(possibly indirectly) occur in the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the order of
dependencies.
\index{move … before … (tactic variant)@\spxentry{move … before …}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.move-_u2026-before-_u2026}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~before~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}
\sphinxAtStartPar
This moves \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} towards and just before the hypothesis
named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}.  As for {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.move}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move}}}}}, dependencies
over \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} (when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} comes before \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}}
(when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} comes after \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the order of
dependencies) are moved too.

\end{fulllineitems}\end{savenotes}

\index{move … at top (tactic variant)@\spxentry{move … at top}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.move-_u2026-at-top}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~at~top}}}}
\sphinxAtStartPar
This moves {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} at the top of the local context (at the beginning
of the context).

\end{fulllineitems}\end{savenotes}

\index{move … at bottom (tactic variant)@\spxentry{move … at bottom}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.move-_u2026-at-bottom}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~at~bottom}}}}
\sphinxAtStartPar
This moves {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} at the bottom of the local context (at the end of
the context).

\end{fulllineitems}\end{savenotes}

\index{No such hypothesis (error)@\spxentry{No such hypothesis}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id9}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis.}}}}
\end{fulllineitems}\end{savenotes}

\index{Cannot move ‘ident’ after ‘ident’: it occurs in the type of ‘ident’ (error)@\spxentry{Cannot move ‘ident’ after ‘ident’: it occurs in the type of ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.Cannot-move-_u2018ident_u2019-after-_u2018ident_u2019:-it-occurs-in-the-type-of-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~move~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~after~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}:~it~occurs~in~the~type~of~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{Cannot move ‘ident’ after ‘ident’: it depends on ‘ident’ (error)@\spxentry{Cannot move ‘ident’ after ‘ident’: it depends on ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.Cannot-move-_u2018ident_u2019-after-_u2018ident_u2019:-it-depends-on-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~move~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~after~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}:~it~depends~on~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}}}
\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:}\PYG{n}{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{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
      
      \PYG{n}{z}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
      
      \PYG{n}{z}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}\end{savenotes}

\index{rename (tactic)@\spxentry{rename}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.rename}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rename~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~into~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}
\sphinxAtStartPar
This renames hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the current
context. The name of the hypothesis in the proof\sphinxhyphen{}term, however, is left
unchanged.


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rename~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}~into~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{j}}$}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This renames the variables \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}} into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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}\end{savenotes}

\index{No such hypothesis (error)@\spxentry{No such hypothesis}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id10}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘ident’ is already used (error)@\spxentry{‘ident’ is already used}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id11}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~used.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{set (tactic)@\spxentry{set}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.set}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\sphinxAtStartPar
This replaces {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} by {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to the
local context.

\sphinxAtStartPar
If {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} has holes (i.e. subexpressions of the form “\sphinxcode{\sphinxupquote{\_}}”), 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 (error)@\spxentry{The variable ‘ident’ is already defined}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.The-variable-_u2018ident_u2019-is-already-defined}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~variable~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~defined.}}}}
\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
\sphinxAtStartPar
This notation allows specifying which occurrences of {\hyperref[\detokenize{language/core/basic: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:occurrencessets}]{\sphinxcrossref{\DUrole{std,std-ref}{goal occurrences}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{language/core/basic: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}{?}}}}}}
\sphinxAtStartPar
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{set ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} => {\hyperref[\detokenize{language/core/basic: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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/core/basic: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}{?}}}}}}
\sphinxAtStartPar
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{set ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is generated by Coq.

\end{fulllineitems}\end{savenotes}

\index{eset (tactic variant)@\spxentry{eset}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{language/core/basic: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:id12}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eset~{\hyperref[\detokenize{language/core/basic: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}{?}}}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} does
not occur in the goal.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{remember (tactic)@\spxentry{remember}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.remember}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{remember~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{set ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}) in *}}}, using a logical
(Leibniz’s) equality instead of a local definition.
Use \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}}} to name or split up the new equation.


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{remember~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}\DUrole{notation-sup}{?}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} specified by an occurrence set.

\end{fulllineitems}\end{savenotes}

\index{eremember (tactic variant)@\spxentry{eremember}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}\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}{?}}}}}}
\sphinxAtStartPar
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{savenotes}


\end{fulllineitems}\end{savenotes}

\index{pose (tactic)@\spxentry{pose}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.pose}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\sphinxAtStartPar
This adds the local definition \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}) in |\sphinxhyphen{}}}}.


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\sphinxAtStartPar
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{pose ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{pose ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} but {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is
generated by Coq.

\end{fulllineitems}\end{savenotes}

\index{epose (tactic variant)@\spxentry{epose}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.epose}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{epose~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}\phantomsection\label{\detokenize{proof-engine/tactics:id13}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{epose~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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{savenotes}


\end{fulllineitems}\end{savenotes}

\index{decompose (tactic)@\spxentry{decompose}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.decompose}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{decompose~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}{]}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic recursively decomposes a complex proposition in order to
obtain atomic ones.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{C}
    \PYG{n}{goal} \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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.decompose}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decompose}}}}} does not work on right\sphinxhyphen{}hand sides of implications or
products.
\end{sphinxadmonition}


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{decompose~sum~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This decomposes sum types (like \sphinxcode{\sphinxupquote{\DUrole{name}{or}}}).

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{decompose~record~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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/core/records:coq:cmd.Record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}}
command.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\subsubsection{Controlling the proof flow}
\label{\detokenize{proof-engine/tactics:controlling-the-proof-flow}}\label{\detokenize{proof-engine/tactics:controllingtheproofflow}}\index{assert (tactic)@\spxentry{assert}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.assert}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}}}
\sphinxAtStartPar
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}}} \sphinxstepexplicit %
\begin{footnote}[2]\phantomsection\label{\thesphinxscope.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.
\index{Not a proposition or a type (error)@\spxentry{Not a proposition or a type}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
Arises when the argument {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} 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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
\sphinxAtStartPar
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}} but \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is
generated by Coq.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}}
\sphinxAtStartPar
This tactic behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert}}}}} but applies tactic to solve the
subgoals generated by assert.
\index{Proof is not complete. (assert) (error)@\spxentry{Proof is not complete. (assert)}\spxextra{error}}

\begin{savenotes}\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{savenotes}


\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{simple\_intropattern}}} is an intro pattern (see {\hyperref[\detokenize{proof-engine/tactics:intropatterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Intro patterns}}}}),
the hypothesis is named after this introduction pattern (in particular, if
\sphinxcode{\sphinxupquote{\DUrole{notation}{simple\_intropattern}}} is \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, the tactic behaves like
\sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}}). If \sphinxcode{\sphinxupquote{\DUrole{notation}{simple\_intropattern}}} is an action
introduction pattern, the tactic behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{assert {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} followed by
the action done by this introduction pattern.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}~by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}}
\sphinxAtStartPar
This combines the two previous variants of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\sphinxAtStartPar
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}) by exact {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} where
{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} is the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. This is equivalent to using
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.pose-proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose proof}}}}}. If the head of term is {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, the tactic
behaves as {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.specialize}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specialize}}}}}.
\index{Variable ‘ident’ is already declared (error)@\spxentry{Variable ‘ident’ is already declared}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.Variable-_u2018ident_u2019-is-already-declared}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Variable~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~declared.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{eassert (tactic variant)@\spxentry{eassert}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eassert}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eassert~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}~by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}}
\sphinxAtStartPar
While the different variants of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert}}}}} expect that no existential
variables are generated by the tactic, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eassert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eassert}}}}} removes this constraint.
This lets you avoid specifying the asserted statement completely before starting
to prove it.

\end{fulllineitems}\end{savenotes}

\index{pose proof (tactic variant)@\spxentry{pose proof}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This tactic behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{assert {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{as {\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}} by exact {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
where {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} is the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. In particular,
\sphinxcode{\sphinxupquote{\DUrole{notation}{pose proof {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{pose proof {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as {\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}} is the same as applying the
{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_intropattern}}}}} to {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\end{fulllineitems}\end{savenotes}

\index{epose proof (tactic variant)@\spxentry{epose proof}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.epose-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{epose~proof~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
While {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.pose-proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose proof}}}}} expects that no existential variables are generated by
the tactic, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.epose-proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{epose proof}}}}} removes this constraint.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~proof~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\sphinxAtStartPar
This is an alternative syntax for \sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{pose proof {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, following the model of \sphinxcode{\sphinxupquote{\DUrole{notation}{pose
({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} but dropping the value of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{epose~proof~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\sphinxAtStartPar
This is an alternative syntax for \sphinxcode{\sphinxupquote{\DUrole{notation}{eassert ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{epose proof {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, following the model of
\sphinxcode{\sphinxupquote{\DUrole{notation}{epose ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} but dropping the value of
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}\end{savenotes}

\index{enough (tactic variant)@\spxentry{enough}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}}}
\sphinxAtStartPar
This adds a new hypothesis of name {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} asserting {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} to the
goal the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.enough}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{enough}}}}} is applied to. A new subgoal stating {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} is
inserted after the initial goal rather than before it as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert}}}}} would do.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
\sphinxAtStartPar
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{enough ({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}} with the name {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} of
the hypothesis generated by Coq.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}}}
\sphinxAtStartPar
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{enough {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} using {\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_intropattern}}}}} to name or
destruct the new hypothesis.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})~by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}~by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}}
\sphinxAtStartPar
This behaves as above but with {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic}}}}} expected to solve the initial goal
after the extra assumption {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} is added and possibly destructed. If the
\sphinxcode{\sphinxupquote{\DUrole{notation}{as {\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}} clause generates more than one subgoal, {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic}}}}} is
applied to all of them.

\end{fulllineitems}\end{savenotes}

\index{eenough (tactic variant)@\spxentry{eenough}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proof-engine/tactics:id15}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eenough~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
While the different variants of {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.enough}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{enough}}}}} expect that no existential
variables are generated by the tactic, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eenough}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eenough}}}}} removes this constraint.

\end{fulllineitems}\end{savenotes}

\index{cut (tactic variant)@\spxentry{cut}\spxextra{tactic variant}}

\begin{savenotes}\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/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
\sphinxAtStartPar
This tactic applies to any goal. It implements the non\sphinxhyphen{}dependent case of
the “App” rule given in {\hyperref[\detokenize{language/cic:id4}]{\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}{\sphinxhyphen{}>} \DUrole{name}{T}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{U}}}. The subgoal \sphinxcode{\sphinxupquote{\DUrole{name}{U} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{T}}} comes first in the
list of remaining subgoal to prove.

\end{fulllineitems}\end{savenotes}

\index{specialize (tactic variant)@\spxentry{specialize}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.specialize}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{specialize~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}})~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proof-engine/tactics:id16}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{specialize~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This tactic works on local hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. The
premises of this hypothesis (either universal quantifications or
non\sphinxhyphen{}dependent implications) are instantiated by concrete terms coming either
from arguments \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}}}} or from {\hyperref[\detokenize{proof-engine/tactics:bindings}]{\sphinxcrossref{\DUrole{std,std-ref}{Bindings}}}}.
In the first form the application to \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is left unchanged and instead, the modified hypothesis
is introduced as specified by the {\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_intropattern}}}}}. The name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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 {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.specialize}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specialize}}}}} is close to that of
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.generalize}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{generalize}}}}}: the instantiated statement becomes an additional premise of
the goal. The \sphinxcode{\sphinxupquote{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’ (error)@\spxentry{‘ident’ is used in hypothesis ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn._u2018ident_u2019-is-used-in-hypothesis-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~used~in~hypothesis~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘ident’ is used in conclusion (error)@\spxentry{‘ident’ is used in conclusion}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn._u2018ident_u2019-is-used-in-conclusion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~used~in~conclusion.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{generalize (tactic)@\spxentry{generalize}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.generalize}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic applies to any goal. It generalizes the conclusion with
respect to some term.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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{n}{nat}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
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{name,builtin,pseudo}{′}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{G}\DUrole{name,builtin,pseudo}{′}}}
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{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}; ... ; generalize {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.
Note that the sequence of term $_{\text{i}}$ 's are processed from n to 1.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but it generalizes only over the
specified occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} (counting from left to right on the
expression printed using the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} flag).

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but it uses \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} to name
the generalized hypothesis.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{+}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This is the most general form of \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize}}} that combines the previous
behaviors.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~dependent~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This generalizes term but also \sphinxstyleemphasis{all} hypotheses that depend on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. It
clears the generalized hypotheses.

\end{fulllineitems}\end{savenotes}

\index{evar (tactic)@\spxentry{evar}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.evar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{evar~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{evar}}} tactic creates a new local definition named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} with type
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} in the context. The body of this binding is a fresh existential
variable.

\end{fulllineitems}\end{savenotes}

\index{instantiate (tactic)@\spxentry{instantiate}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.instantiate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} with the term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. It is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{only {[}ident{]}: refine {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} (preferred alternative).

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
To be able to refer to an existential variable by name, the user
must have given the name explicitly (see {\hyperref[\detokenize{language/extensions/evars:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}).
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~({\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\sphinxAtStartPar
This variant selects an existential variable by its position.  The
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} argument is the position of the existential variable
\sphinxstyleemphasis{from right to left} in the conclusion of the goal.  (Use one of
the variants below to select an existential variable in a
hypothesis.)  Counting starts at 1 and multiple occurrences of the
same existential variable are counted multiple times.  Because this
variant is not robust to slight changes in the goal, its use is
strongly discouraged.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~(~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)~in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~(~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)~in~(~value~of~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~)}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~(~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)~in~(~type~of~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~)}}}}
\sphinxAtStartPar
These allow to refer respectively to existential variables occurring in a
hypothesis or in the body or the type of a local definition (named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}).

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{admit (tactic)@\spxentry{admit}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.admit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{admit}}}}
\sphinxAtStartPar
This 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 {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} but only with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Admitted}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Admitted}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{give\_up}}}}
\sphinxAtStartPar
Synonym of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.admit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{admit}}}}}.

\end{fulllineitems}\end{savenotes}

\index{absurd (tactic)@\spxentry{absurd}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.absurd}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{absurd~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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{name,builtin,pseudo}{∼}\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{name,builtin,pseudo}{∼}\DUrole{name}{P}}} is one of the hypotheses of the
local context.

\end{fulllineitems}\end{savenotes}

\index{contradiction (tactic)@\spxentry{contradiction}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.contradiction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{contradiction}}}}
\sphinxAtStartPar
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.
\index{No such assumption (error)@\spxentry{No such assumption}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id17}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~assumption.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{contradiction~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
The proof of False is searched in the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{contradict (tactic)@\spxentry{contradict}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.contradict}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{contradict~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This tactic allows manipulating negated hypothesis and goals. The name
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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 {} 
\sphinxAtStartPar
H:¬A ⊢ B becomes ⊢ A

\item {} 
\sphinxAtStartPar
H:¬A ⊢ ¬B becomes H: B ⊢ A

\item {} 
\sphinxAtStartPar
H: A ⊢ B becomes ⊢ ¬A

\item {} 
\sphinxAtStartPar
H: A ⊢ ¬B becomes H: B ⊢ ¬A

\end{itemize}

\end{fulllineitems}\end{savenotes}

\index{exfalso (tactic)@\spxentry{exfalso}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.exfalso}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exfalso}}}}
\sphinxAtStartPar
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}\end{savenotes}



\subsubsection{Checking properties of terms}
\label{\detokenize{proof-engine/tactics:checking-properties-of-terms}}
\sphinxAtStartPar
Each of the following tactics acts as the identity if the check
succeeds, and results in an error otherwise.
\index{constr\_eq (tactic)@\spxentry{constr\_eq}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.constr_eq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{constr\_eq~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic checks whether its arguments are equal modulo alpha
conversion, casts and universe constraints. It may unify universes.

\end{fulllineitems}\end{savenotes}

\index{Not equal (error)@\spxentry{Not equal}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{Not equal (due to universes) (error)@\spxentry{Not equal (due to universes)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.Not-equal-(due-to-universes)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~equal~(due~to~universes).}}}}
\end{fulllineitems}\end{savenotes}

\index{constr\_eq\_strict (tactic)@\spxentry{constr\_eq\_strict}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.constr_eq_strict}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{constr\_eq\_strict~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic checks whether its arguments are equal modulo alpha
conversion, casts and universe constraints. It does not add new
constraints.

\end{fulllineitems}\end{savenotes}

\index{Not equal (error)@\spxentry{Not equal}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id18}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~equal.}}}}
\end{fulllineitems}\end{savenotes}

\index{Not equal (due to universes) (error)@\spxentry{Not equal (due to universes)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id19}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~equal~(due~to~universes).}}}}
\end{fulllineitems}\end{savenotes}

\index{unify (tactic)@\spxentry{unify}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.unify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unify~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic checks whether its arguments are unifiable, potentially
instantiating existential variables.

\end{fulllineitems}\end{savenotes}

\index{Unable to unify ‘term’ with ‘term’ (error)@\spxentry{Unable to unify ‘term’ with ‘term’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:id20}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~unify~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unify~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Unification takes the transparency information defined in the hint database
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} into account (see {\hyperref[\detokenize{proofs/automatic-tactics/auto:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{the hints databases for auto and eauto}}}}).

\end{fulllineitems}\end{savenotes}

\index{is\_evar (tactic)@\spxentry{is\_evar}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.is_evar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{is\_evar~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{Not an evar (error)@\spxentry{Not an evar}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{has\_evar (tactic)@\spxentry{has\_evar}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.has_evar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{has\_evar~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{No evars (error)@\spxentry{No evars}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{is\_var (tactic)@\spxentry{is\_var}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.is_var}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{is\_var~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic checks whether its argument is a variable or hypothesis in
the current local context.

\end{fulllineitems}\end{savenotes}

\index{Not a variable or hypothesis (error)@\spxentry{Not a variable or hypothesis}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}



\subsubsection{Classical tactics}
\label{\detokenize{proof-engine/tactics:classical-tactics}}
\sphinxAtStartPar
In order to ease the proving process, when the \sphinxcode{\sphinxupquote{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 (tactic)@\spxentry{classical\_left}\spxextra{tactic}}\index{classical\_right (tactic)@\spxentry{classical\_right}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.classical_left}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{classical\_left}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.classical_right}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{classical\_right}}}}
\sphinxAtStartPar
These tactics are the analog of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.left}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{left}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.right}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{right}}}}}
but using classical logic. They can only be used for
disjunctions. Use {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.classical_left}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{classical\_left}}}}} to prove the left part of the
disjunction with the assumption that the negation of right part holds.
Use {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.classical_right}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{classical\_right}}}}} to prove the right part of the disjunction with
the assumption that the negation of left part holds.

\end{fulllineitems}\end{savenotes}



\subsubsection{Delaying solving unification constraints}
\label{\detokenize{proof-engine/tactics:delaying-solving-unification-constraints}}\index{solve\_constraints (tactic)@\spxentry{solve\_constraints}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.solve_constraints}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{solve\_constraints}}}}
\end{fulllineitems}\end{savenotes}

\index{Solve Unification Constraints (flag)@\spxentry{Solve Unification Constraints}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.Solve-Unification-Constraints}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Solve~Unification~Constraints}}}}
\sphinxAtStartPar
By default, after each tactic application, postponed typechecking unification
problems are resolved using heuristics. Unsetting this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} disables this
behavior, allowing tactics to leave unification constraints unsolved. Use the
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.solve_constraints}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve\_constraints}}}}} tactic at any point to solve the constraints.

\end{fulllineitems}\end{savenotes}



\subsubsection{Proof maintenance}
\label{\detokenize{proof-engine/tactics:proof-maintenance}}
\sphinxAtStartPar
\sphinxstyleemphasis{Experimental.}  Many tactics, such as {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}}, can automatically generate names, such
as "H0" or "H1" for a new hypothesis introduced from a goal.  Subsequent proof steps
may explicitly refer to these names.  However, future versions of Coq may not assign
names exactly the same way, which could cause the proof to fail because the
new names don't match the explicit references in the proof.

\sphinxAtStartPar
The following "Mangle Names" settings let users find all the
places where proofs rely on automatically generated names, which can
then be named explicitly to avoid any incompatibility.  These
settings cause Coq to generate different names, producing errors for
references to automatically generated names.
\index{Mangle Names (flag)@\spxentry{Mangle Names}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.Mangle-Names}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Mangle~Names}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is set (it is off by default),
generated names use the prefix specified in the following
option instead of the default prefix.

\end{fulllineitems}\end{savenotes}

\index{Mangle Names Prefix (option)@\spxentry{Mangle Names Prefix}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:opt.Mangle-Names-Prefix}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Mangle~Names~Prefix~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} specifies the prefix to use when generating names.

\end{fulllineitems}\end{savenotes}



\subsubsection{Performance\sphinxhyphen{}oriented tactic variants}
\label{\detokenize{proof-engine/tactics:performance-oriented-tactic-variants}}\index{exact\_no\_check (tactic)@\spxentry{exact\_no\_check}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.exact_no_check}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exact\_no\_check~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
For advanced usage. Similar to {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, but as an optimization,
it skips checking that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} has the goal's type, relying on the kernel
check instead. See {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change\_no\_check}}}}} for more explanation.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{False}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{exact\PYGZus{}no\PYGZus{}check} \PYG{n}{I}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{n}{Fail} \PYG{k+kn}{Qed}\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}{I}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{True}\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}{False}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{vm\_cast\_no\_check (tactic variant)@\spxentry{vm\_cast\_no\_check}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.vm_cast_no_check}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{vm\_cast\_no\_check~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
For advanced usage. Similar to {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact\_no\_check}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, but additionally
instructs the kernel to use {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}} to compare the
goal's type with the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}'s type.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{False}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{vm\PYGZus{}cast\PYGZus{}no\PYGZus{}check} \PYG{n}{I}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{n}{Fail} \PYG{k+kn}{Qed}\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}{I}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{True}\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}{False}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{native\_cast\_no\_check (tactic variant)@\spxentry{native\_cast\_no\_check}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.native_cast_no_check}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{native\_cast\_no\_check~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
for advanced usage. similar to {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact\_no\_check}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, but additionally
instructs the kernel to use {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} to compare the goal's
type with the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}'s type.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{False}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{native\PYGZus{}cast\PYGZus{}no\PYGZus{}check} \PYG{n}{I}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{n}{Fail} \PYG{k+kn}{Qed}\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}{I}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{True}\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}{False}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\subsection{Reasoning with equalities}
\label{\detokenize{proofs/writing-proofs/equality:reasoning-with-equalities}}\label{\detokenize{proofs/writing-proofs/equality::doc}}
\sphinxAtStartPar
There are multiple notions of \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-equality}}equality} in Coq:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-Leibniz-equality}}Leibniz equality} is the standard
way to define equality in Coq and the Calculus of Inductive Constructions,
which is in terms of a binary relation, i.e. a binary function that returns
a \sphinxcode{\sphinxupquote{Prop}}.  The standard library
defines \sphinxcode{\sphinxupquote{eq}} similar to this:
\begin{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{eq} \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}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{eq\PYGZus{}refl} \PYG{o}{:} \PYG{n}{eq} \PYG{n}{x} \PYG{n}{x}\PYG{o}{.}
\end{sphinxVerbatim}
\end{quote}

\sphinxAtStartPar
The notation \sphinxcode{\sphinxupquote{x = y}} represents the term \sphinxcode{\sphinxupquote{eq x y}}.  The notation \sphinxcode{\sphinxupquote{x = y :> A}}
gives the type of x and y explicitly.

\item {} 
\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-setoid-equality}}Setoid equality} defines equality in terms of an equivalence
relation.  A \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-setoid}}setoid} is a set that is equipped with an equivalence relation
(see \sphinxurl{https://en.wikipedia.org/wiki/Setoid}).  These are needed to form a \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-quotient-set}}quotient set}
or \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-quotient}}quotient}
(see \sphinxurl{https://en.wikipedia.org/wiki/Equivalence\_Class}).  In Coq, users generally work
with setoids rather than constructing quotients, for which there is no specific support.

\item {} 
\sphinxAtStartPar
\DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-definitional-equality}}Definitional equality} is equality based on the
{\hyperref[\detokenize{language/core/conversion:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{conversion rules}}}}, which Coq can determine automatically.
When two terms are definitionally equal, Coq knows it can
replace one with the other, such as with {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}} \sphinxcode{\sphinxupquote{X with Y}}, among many
other advantages.  "{\hyperref[\detokenize{language/core/conversion:term-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{Convertible}}}}" is another way of saying that
two terms are definitionally equal.

\end{itemize}


\subsubsection{Tactics for simple equalities}
\label{\detokenize{proofs/writing-proofs/equality:tactics-for-simple-equalities}}\index{reflexivity (tactic)@\spxentry{reflexivity}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.reflexivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{reflexivity}}}}
\sphinxAtStartPar
For a goal with the form \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} ,}\DUrole{notation-sup}{?}} t = u}}},
verifies that \sphinxcode{\sphinxupquote{t}} and \sphinxcode{\sphinxupquote{u}} are
{\hyperref[\detokenize{proofs/writing-proofs/equality:term-definitional-equality}]{\sphinxtermref{\DUrole{xref,std,std-term}{definitionally equal}}}}, and if so,
solves the goal (by applying \sphinxcode{\sphinxupquote{eq\_refl}}).  If not, it fails.

\sphinxAtStartPar
The tactic may also be applied to goals with the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} ,}\DUrole{notation-sup}{?}} R {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} where
\sphinxcode{\sphinxupquote{R}} is a reflexive relation registered with the \sphinxcode{\sphinxupquote{Equivalence}} or \sphinxcode{\sphinxupquote{Reflexive}}
typeclasses.  See {\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}}}}}.
\index{The relation ‘ident’ is not a declared reflexive relation. Maybe you need to require the Coq.Classes.RelationClasses library (error)@\spxentry{The relation ‘ident’ is not a declared reflexive relation. Maybe you need to require the Coq.Classes.RelationClasses library}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.The-relation-_u2018ident_u2019-is-not-a-declared-reflexive-relation.-Maybe-you-need-to-require-the-Coq.Classes.RelationClasses-library}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~relation~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~not~a~declared~reflexive~relation.~Maybe~you~need~to~require~the~Coq.Classes.RelationClasses~library}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{symmetry (tactic)@\spxentry{symmetry}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.symmetry}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{symmetry~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Changes a goal that has the form \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} ,}\DUrole{notation-sup}{?}} t = u}}} into
\sphinxcode{\sphinxupquote{\DUrole{notation}{u = t}}}.  \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}
may be used to apply the change in the selected hypotheses and/or the conclusion.

\sphinxAtStartPar
The tactic may also be applied to goals with the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} ,}\DUrole{notation-sup}{?}} R {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} where
\sphinxcode{\sphinxupquote{R}} is a symmetric relation registered with the \sphinxcode{\sphinxupquote{Equivalence}} or \sphinxcode{\sphinxupquote{Symmetric}}
typeclasses.  See {\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}}}}}.
\index{The relation ‘ident’ is not a declared symmetric relation. Maybe you need to require the Coq.Classes.RelationClasses library (error)@\spxentry{The relation ‘ident’ is not a declared symmetric relation. Maybe you need to require the Coq.Classes.RelationClasses library}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.The-relation-_u2018ident_u2019-is-not-a-declared-symmetric-relation.-Maybe-you-need-to-require-the-Coq.Classes.RelationClasses-library}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~relation~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~not~a~declared~symmetric~relation.~Maybe~you~need~to~require~the~Coq.Classes.RelationClasses~library}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{transitivity (tactic)@\spxentry{transitivity}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.transitivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{transitivity~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}
\sphinxAtStartPar
Changes a goal that has the form \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} ,}\DUrole{notation-sup}{?}} t = u}}}
into the two subgoals \sphinxcode{\sphinxupquote{\DUrole{notation}{t = {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} = u}}}.

\sphinxAtStartPar
The tactic may also be applied to goals with the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} ,}\DUrole{notation-sup}{?}} R {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} where
\sphinxcode{\sphinxupquote{R}} is a transitive relation registered with the \sphinxcode{\sphinxupquote{Equivalence}} or \sphinxcode{\sphinxupquote{Transitivity}}
typeclasses.  See {\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}}}}}.
\index{etransitivity (tactic)@\spxentry{etransitivity}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.etransitivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{etransitivity}}}}
\sphinxAtStartPar
This tactic behaves like {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.transitivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{transitivity}}}}}, using a fresh evar instead of
a concrete {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}.

\end{fulllineitems}\end{savenotes}

\index{The relation ‘ident’ is not a declared transitive relation. Maybe you need to require the Coq.Classes.RelationClasses library (error)@\spxentry{The relation ‘ident’ is not a declared transitive relation. Maybe you need to require the Coq.Classes.RelationClasses library}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.The-relation-_u2018ident_u2019-is-not-a-declared-transitive-relation.-Maybe-you-need-to-require-the-Coq.Classes.RelationClasses-library}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~relation~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~not~a~declared~transitive~relation.~Maybe~you~need~to~require~the~Coq.Classes.RelationClasses~library}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{f\_equal (tactic)@\spxentry{f\_equal}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.f_equal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{f\_equal}}}}
\sphinxAtStartPar
For a goal with the form \sphinxcode{\sphinxupquote{\DUrole{notation}{f a$_{\text{1}}$ ... a$_{\text{n}}$ = g b$_{\text{1}}$ ... b$_{\text{n}}$}}}, creates
subgoals \sphinxcode{\sphinxupquote{\DUrole{notation}{f = g}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{a$_{\text{i}}$ = b$_{\text{i}}$}}} for the \sphinxcode{\sphinxupquote{n}} arguments. Subgoals
that can be proven by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}} or {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}} are solved
automatically.

\end{fulllineitems}\end{savenotes}



\subsubsection{Rewriting with Leibniz and setoid equality}
\label{\detokenize{proofs/writing-proofs/equality:rewriting-with-leibniz-and-setoid-equality}}\label{\detokenize{proofs/writing-proofs/equality:rewritingexpressions}}\index{rewrite (tactic)@\spxentry{rewrite}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-oriented_rewriter}]{\sphinxcrossref{\DUrole{hole}{oriented\_rewriter}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-oriented_rewriter}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-oriented_rewriter}]{\sphinxcrossref{\DUrole{hole}{oriented\_rewriter}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{?}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{!}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-one_term_with_bindings}]{\sphinxcrossref{\DUrole{hole}{one\_term\_with\_bindings}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-one_term_with_bindings}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-one_term_with_bindings}]{\sphinxcrossref{\DUrole{hole}{one\_term\_with\_bindings}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{>}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Replaces subterms with other subterms that have been proven to be equal.
The type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} must have the form:
\begin{quote}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}} ,}\DUrole{notation-sup}{?}} EQ {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}}
\end{quote}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{\DUrole{name}{EQ}}} is the Leibniz equality \sphinxcode{\sphinxupquote{eq}} or a registered {\hyperref[\detokenize{proofs/writing-proofs/equality:term-setoid-equality}]{\sphinxtermref{\DUrole{xref,std,std-term}{setoid equality}}}}.
Note that \sphinxcode{\sphinxupquote{\DUrole{notation}{eq {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} is typically written with the infix notation
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}}.  You must \sphinxcode{\sphinxupquote{Require Setoid}} to use the tactic
with a setoid equality or with {\hyperref[\detokenize{addendum/generalized-rewriting:generalizedrewriting}]{\sphinxcrossref{\DUrole{std,std-ref}{setoid rewriting}}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} finds subterms matching \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}} in the goal,
and replaces them with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} (or the reverse if \sphinxcode{\sphinxupquote{<\sphinxhyphen{}}} is given).
Some of the variables \sphinxcode{\sphinxupquote{\DUrole{name}{x}}}$_{\text{i}}$ are solved by unification,
and some of the types \sphinxcode{\sphinxupquote{\DUrole{notation}{A$_{\text{1}}$, …, A$_{\text{n}}$}}} may become new
subgoals.  {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} won't find occurrences inside \sphinxcode{\sphinxupquote{forall}} that refer
to variables bound by the \sphinxcode{\sphinxupquote{forall}}; use the more advanced {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}}
if you want to find such occurrences.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-oriented_rewriter}]{\sphinxcrossref{\DUrole{hole}{oriented\_rewriter}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}] \leavevmode
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-oriented_rewriter}]{\sphinxcrossref{\DUrole{hole}{oriented\_rewriter}}}}}}}s are applied sequentially
to the first goal generated by the previous \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-oriented_rewriter}]{\sphinxcrossref{\DUrole{hole}{oriented\_rewriter}}}}}}}.  If any of them fail,
the tactic fails.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
For \sphinxcode{\sphinxupquote{\sphinxhyphen{}>}} (the default), \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}} is rewritten
into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}}.  For \sphinxcode{\sphinxupquote{<\sphinxhyphen{}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} is rewritten into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{?}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{!}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} is the number of rewrites to perform.  If \sphinxcode{\sphinxupquote{?}} is given, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}
is the maximum number of rewrites to perform; otherwise \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} is the exact number
of rewrites to perform.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{?}} (without \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}) performs the rewrite as many times as possible
(possibly zero times).
This form never fails.  \sphinxcode{\sphinxupquote{!}} (without \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}) performs the rewrite as many
times as possible
and at least once.  The tactic fails if the requested number of rewrites can't
be performed.  \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}} !}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}} specifies multiple occurrences, the tactic succeeds if
any of them can be rewritten.  If not specified, only the first occurrence
in the conclusion is replaced.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}}} is specified, rewriting is always done
with {\hyperref[\detokenize{addendum/generalized-rewriting:generalizedrewriting}]{\sphinxcrossref{\DUrole{std,std-ref}{setoid rewriting}}}}, even for
Leibniz equality, which means that you must \sphinxcode{\sphinxupquote{Require
Setoid}} to use that form.  However, note that {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}
(even when using setoid rewriting) and {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}}
don't behave identically (as is noted above and below).
\end{sphinxadmonition}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{by {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}] \leavevmode
\sphinxAtStartPar
If specified, is used to resolve all side conditions generated by the tactic.

\end{description}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
For each selected hypothesis and/or the conclusion,
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} finds the first matching subterm in
depth\sphinxhyphen{}first search order. Only subterms identical to
that first matched subterm are rewritten.  If the \sphinxcode{\sphinxupquote{at}} clause is specified,
only these subterms are considered when counting occurrences.
To select a different set of matching subterms, you can
specify how some or all of the free variables are bound by
using a \sphinxcode{\sphinxupquote{with}} clause (see \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-one_term_with_bindings}]{\sphinxcrossref{\DUrole{hole}{one\_term\_with\_bindings}}}}}}}).

\sphinxAtStartPar
For instance, if we want to rewrite the right\sphinxhyphen{}hand side in the
following goal, this will not work:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}comm} \PYG{n}{at} \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}{25}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{rewrite} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}comm} \PYG{n}{at} \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{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\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}{Invalid} \PYG{n}{occurrence} \PYG{n}{number}\PYG{o}{:} \PYG{l+m+mi}{2}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
One can explicitly specify how some variables are bound to match
a different subterm:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}comm} \PYG{k}{with} \PYG{o}{(}\PYG{n}{m} \PYG{o}{:=} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Note that the more advanced {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} tactic
behaves differently, and thus the number of occurrences
available to rewrite may differ between the two tactics.
\end{sphinxadmonition}
\index{Tactic failure: Setoid library not loaded (error)@\spxentry{Tactic failure: Setoid library not loaded}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Tactic-failure:-Setoid-library-not-loaded}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~failure:~Setoid~library~not~loaded.}}}}~
\end{fulllineitems}\end{savenotes}

\index{Cannot find a relation to rewrite (error)@\spxentry{Cannot find a relation to rewrite}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Cannot-find-a-relation-to-rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~a~relation~to~rewrite.}}}}
\end{fulllineitems}\end{savenotes}

\index{Tactic generated a subgoal identical to the original goal (error)@\spxentry{Tactic generated a subgoal identical to the original goal}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Tactic-generated-a-subgoal-identical-to-the-original-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~generated~a~subgoal~identical~to~the~original~goal.}}}}
\end{fulllineitems}\end{savenotes}

\index{Found no subterm matching ‘term’ in ‘ident’ (error)@\spxentry{Found no subterm matching ‘term’ in ‘ident’}\spxextra{error}}\index{Found no subterm matching ‘term’ in the current goal (error)@\spxentry{Found no subterm matching ‘term’ in the current goal}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Found-no-subterm-matching-_u2018term_u2019-in-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Found~no~subterm~matching~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Found-no-subterm-matching-_u2018term_u2019-in-the-current-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Found~no~subterm~matching~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~the~current~goal.}}}}
\sphinxAtStartPar
This happens if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} does not occur in, respectively, the named hypothesis or the goal.

\end{fulllineitems}\end{savenotes}

\index{erewrite (tactic)@\spxentry{erewrite}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.erewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{erewrite~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-oriented_rewriter}]{\sphinxcrossref{\DUrole{hole}{oriented\_rewriter}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Works like {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}, but turns
unresolved bindings, if any, into existential variables instead of
failing. It has the same parameters as {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Keyed Unification (flag)@\spxentry{Keyed Unification}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:flag.Keyed-Unification}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Keyed~Unification}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} makes higher\sphinxhyphen{}order unification used by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} rely on a set of keys to drive
unification.  The subterms, considered as rewriting candidates, must start with
the same key as the left\sphinxhyphen{} or right\sphinxhyphen{}hand side of the lemma given to rewrite, and the arguments
are then unified up to full reduction.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{rewrite * (tactic)@\spxentry{rewrite *}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite-*}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~*~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{at~{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewrite_occs}]{\sphinxcrossref{\DUrole{hole}{rewrite\_occs}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/equality:id1}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~*~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~at~{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewrite_occs}]{\sphinxcrossref{\DUrole{hole}{rewrite\_occs}}}}~in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}\end{savenotes}

\index{rewrite\_db (tactic)@\spxentry{rewrite\_db}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite_db}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite\_db~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}\end{savenotes}

\index{replace (tactic)@\spxentry{replace}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.replace}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/equality:id2}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
The first form replaces all free occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}}
in the current goal with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}}}} and generates an equality
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}}
as a subgoal. (Note the generated equality is reversed with respect
to the order of the two terms in the tactic syntax; see
issue \sphinxhref{https://github.com/coq/coq/issues/13480}{\#13480}%
\begin{footnote}[28]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13480}
%
\end{footnote}.)
This equality is automatically solved if it occurs among
the hypotheses, or if its symmetric form occurs.

\sphinxAtStartPar
The second form, with \sphinxcode{\sphinxupquote{\sphinxhyphen{}>}} or no arrow, replaces \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}}
with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{to}}$}}}}}}} using
the first hypothesis whose type has the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{to}}$}}}}}}}.
If \sphinxcode{\sphinxupquote{<\sphinxhyphen{}}} is given, the tactic uses the first hypothesis with the reverse form,
i.e. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{to}}$}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{type of}} and \sphinxcode{\sphinxupquote{value of}} forms are not supported.
Note you must \sphinxcode{\sphinxupquote{Require Setoid}} to use the \sphinxcode{\sphinxupquote{at}} clause in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{by {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}] \leavevmode
\sphinxAtStartPar
Applies the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} to solve the generated equality.

\end{description}
\index{Terms do not have convertible types (error)@\spxentry{Terms do not have convertible types}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality: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}\end{savenotes}

\index{cutrewrite (tactic)@\spxentry{cutrewrite}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.cutrewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cutrewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is an equality.

\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.5: }Use {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}} instead.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{substitute (tactic)@\spxentry{substitute}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.substitute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{substitute~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}\end{savenotes}

\index{subst (tactic)@\spxentry{subst}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.subst}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{subst~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
For each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, in order, for which there is a hypothesis in the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, replaces \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
everywhere in the hypotheses and the conclusion and clears \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} and the hypothesis
from the context.  If there are multiple hypotheses that match the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}},
the first one is used.  If no \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is given, replacement is done for all
hypotheses in the appropriate form in top to bottom order.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a local definition of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, it is also
unfolded and cleared.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a section variable it must have no
indirect occurrences in the goal, i.e. no global declarations
implicitly depending on the section variable may be present in the
goal.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
If the hypothesis is itself dependent in the goal, it is replaced by the proof of
reflexivity of equality.
\end{sphinxadmonition}
\index{Regular Subst Tactic (flag)@\spxentry{Regular Subst Tactic}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:flag.Regular-Subst-Tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Regular~Subst~Tactic}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls the behavior of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}}. When it is
activated (it is by default), {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}} also deals with the following corner cases:
\begin{itemize}
\item {} 
\sphinxAtStartPar
A context with ordered hypotheses \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} = t}}}, or \sphinxcode{\sphinxupquote{\DUrole{notation}{t′ = {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} with \sphinxcode{\sphinxupquote{t′}} not
a variable, and no other hypotheses of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}} = u}}}
or \sphinxcode{\sphinxupquote{\DUrole{notation}{u = {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}; without the flag, a second call to
subst would be necessary to replace \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} by \sphinxcode{\sphinxupquote{t}} or
\sphinxcode{\sphinxupquote{t′}} respectively.

\item {} 
\sphinxAtStartPar
The presence of a recursive equation which without the flag would
be a cause of failure of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}}.

\item {} 
\sphinxAtStartPar
A context with cyclic dependencies as with hypotheses \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} = f {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}} = g {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} which without the
flag would be a cause of failure of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}}.

\end{itemize}

\sphinxAtStartPar
Additionally, it prevents a local definition such as \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := t}}} from being
unfolded which otherwise it would exceptionally unfold in configurations
containing hypotheses of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} = u}}}, or \sphinxcode{\sphinxupquote{\DUrole{notation}{u′ = {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
with \sphinxcode{\sphinxupquote{u′}} not a variable. Finally, it preserves the initial order of
hypotheses, which without the flag it may break.

\end{fulllineitems}\end{savenotes}

\index{Cannot find any non\sphinxhyphen{}recursive equality over ‘ident’ (error)@\spxentry{Cannot find any non\sphinxhyphen{}recursive equality over ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Cannot-find-any-non-recursive-equality-over-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~any~non\sphinxhyphen{}recursive~equality~over~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{Section variable ‘ident’ occurs implicitly in global declaration ‘qualid’ present in hypothesis ‘ident’ (error)@\spxentry{Section variable ‘ident’ occurs implicitly in global declaration ‘qualid’ present in hypothesis ‘ident’}\spxextra{error}}\index{Section variable ‘ident’ occurs implicitly in global declaration ‘qualid’ present in the conclusion (error)@\spxentry{Section variable ‘ident’ occurs implicitly in global declaration ‘qualid’ present in the conclusion}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Section-variable-_u2018ident_u2019-occurs-implicitly-in-global-declaration-_u2018qualid_u2019-present-in-hypothesis-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Section~variable~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~occurs~implicitly~in~global~declaration~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~present~in~hypothesis~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Section-variable-_u2018ident_u2019-occurs-implicitly-in-global-declaration-_u2018qualid_u2019-present-in-the-conclusion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Section~variable~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~occurs~implicitly~in~global~declaration~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~present~in~the~conclusion.}}}}
\sphinxAtStartPar
Raised when the variable is a section variable with indirect
dependencies in the goal.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a section variable, it must not have any
indirect occurrences in the goal, i.e. no global declarations
implicitly depending on the section variable may be present in the
goal.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{simple subst (tactic)@\spxentry{simple subst}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.simple-subst}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~subst}}}}
\end{fulllineitems}\end{savenotes}

\index{stepl (tactic)@\spxentry{stepl}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.stepl}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{stepl~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
For chaining rewriting steps. It assumes a goal in the
form \sphinxcode{\sphinxupquote{\DUrole{notation}{R {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} 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}{\sphinxhyphen{}>} \DUrole{name}{eq} \DUrole{name}{x} \DUrole{name}{z} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{R} \DUrole{name}{z} \DUrole{name}{y}}}
where \sphinxcode{\sphinxupquote{eq}} is typically a setoid equality. The application of \sphinxcode{\sphinxupquote{\DUrole{notation}{stepl {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}
then replaces the goal by \sphinxcode{\sphinxupquote{\DUrole{notation}{R {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{2}}$}}}}}}} and adds a new goal stating
\sphinxcode{\sphinxupquote{\DUrole{notation}{eq {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}}.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} is specified, it is applied to the side condition.
\index{Declare Left Step (command)@\spxentry{Declare Left Step}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Declare-Left-Step}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Left~Step~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}
\sphinxAtStartPar
Adds \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} to the database used by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.stepl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{stepl}}}}}.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
This tactic is especially useful for parametric setoids which are not accepted
as regular setoids for {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} and {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_replace}}}}} (see
{\hyperref[\detokenize{addendum/generalized-rewriting:generalizedrewriting}]{\sphinxcrossref{\DUrole{std,std-ref}{Generalized rewriting}}}}).
\index{stepr (tactic)@\spxentry{stepr}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.stepr}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{stepr~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This behaves like {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.stepl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{stepl}}}}} but on the right hand side of the binary
relation. Lemmas are expected to be in 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}{\sphinxhyphen{}>} \DUrole{name}{eq} \DUrole{name}{y} \DUrole{name}{z} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{R} \DUrole{name}{x} \DUrole{name}{z}}}.

\end{fulllineitems}\end{savenotes}

\index{Declare Right Step (command)@\spxentry{Declare Right Step}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Declare-Right-Step}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Right~Step~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}
\sphinxAtStartPar
Adds \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to the database used by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.stepr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{stepr}}}}}.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\subsubsection{Rewriting with definitional equality}
\label{\detokenize{proofs/writing-proofs/equality:rewriting-with-definitional-equality}}\index{change (tactic)@\spxentry{change}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.change}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{change~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{at~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}~with}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Replaces terms with other {\hyperref[\detokenize{language/core/conversion:term-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{convertible}}}} terms.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}} is not specified, then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}}}} replaces the conclusion and/or
the specified hypotheses.  If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}} is specified, the tactic replaces occurrences
of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}}}} within the conclusion and/or the specified hypotheses.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}} with}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Replaces the occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}} specified by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}}}
with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}}}}, provided that the two \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}s are
convertible.  \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}} may contain pattern variables such as \sphinxcode{\sphinxupquote{?x}},
whose value which will substituted for \sphinxcode{\sphinxupquote{x}} in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}}}}, such as in
\sphinxcode{\sphinxupquote{change (f ?x ?y) with (g (x, y))}} or \sphinxcode{\sphinxupquote{change (fun x => ?f x) with f}}.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{at … with …}} form is deprecated in 8.14; use \sphinxcode{\sphinxupquote{with … at …}} instead.
For \sphinxcode{\sphinxupquote{at … with … in H |\sphinxhyphen{}}}, use \sphinxcode{\sphinxupquote{with … in H at … |\sphinxhyphen{}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{with}} is not specified, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}} must only specify
entire hypotheses and/or the goal; it must not include any
\sphinxcode{\sphinxupquote{\DUrole{notation}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}}} clauses.

\end{description}
\index{Not convertible (error)@\spxentry{Not convertible}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Not-convertible}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~convertible.}}}}
\end{fulllineitems}\end{savenotes}

\index{Found an ""at"" clause without ""with"" clause (error)@\spxentry{Found an ""at"" clause without ""with"" clause}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Found-an-"at"-clause-without-"with"-clause}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Found~an~"at"~clause~without~"with"~clause}}}}
\end{fulllineitems}\end{savenotes}

\index{now\_show (tactic)@\spxentry{now\_show}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.now_show}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{now\_show~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}
\sphinxAtStartPar
A synonym for \sphinxcode{\sphinxupquote{\DUrole{notation}{change {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}. It can be used to
make some proof steps explicit when refactoring a proof script
to make it readable.

\end{fulllineitems}\end{savenotes}



\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:applyingconversionrules}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying conversion rules}}}}



\end{fulllineitems}\end{savenotes}

\index{change\_no\_check (tactic)@\spxentry{change\_no\_check}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.change_no_check}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{change\_no\_check~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{at~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}~with}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
For advanced usage. Similar to {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}}, but as an optimization,
it skips checking that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{to}}$}}}}}}} is convertible with the goal or
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{from}}$}}}}}}}.

\sphinxAtStartPar
Recall that the Coq kernel typechecks proofs again when they are concluded to
ensure correctness. Hence, using {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}} checks convertibility twice
overall, while {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change\_no\_check}}}}} can produce ill\sphinxhyphen{}typed terms,
but checks convertibility only once.
Hence, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change\_no\_check}}}}} can be useful to speed up certain proof
scripts, especially if one knows by construction that the argument is
indeed convertible to the goal.

\sphinxAtStartPar
In the following example, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change\_no\_check}}}}} replaces \sphinxcode{\sphinxupquote{\DUrole{name}{False}}} with
\sphinxcode{\sphinxupquote{\DUrole{name}{True}}}, but {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} then rejects the proof, ensuring consistency.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{False}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{change\PYGZus{}no\PYGZus{}check} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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+kp}{exact} \PYG{n}{I}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\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}{4}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{I}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{True}\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}{False}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}

  \PYG{k}{intro} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \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}{False}

  \PYG{n}{change\PYGZus{}no\PYGZus{}check} \PYG{n}{False} \PYG{k}{in} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{False}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k+kp}{exact} \PYG{n}{H}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\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}{4}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{fun H : True =\PYGZgt{} H}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{True \PYGZhy{}\PYGZgt{} True}\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}{True \PYGZhy{}\PYGZgt{} False}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\subsubsection{Applying conversion rules}
\label{\detokenize{proofs/writing-proofs/equality:applying-conversion-rules}}\label{\detokenize{proofs/writing-proofs/equality:applyingconversionrules}}
\sphinxAtStartPar
These tactics apply reductions and expansions, replacing {\hyperref[\detokenize{language/core/conversion:term-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{convertible}}}} subterms
with others that are equal by definition in CIC.
They implement different specialized uses of the
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}} tactic.  Other ways to apply these reductions are through
the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Eval}}}}} command, the \sphinxcode{\sphinxupquote{Eval}} clause in the {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}/{\hyperref[\detokenize{language/core/definitions:coq:cmd.Example}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Example}}}}}
command and the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eval}}}}} tactic.

\sphinxAtStartPar
Tactics described in this section include:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.lazy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazy}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}}, which allow precise selection of which reduction
rules to apply

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}}, which are "clever" tactics meant to give the most
readable result

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.red}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{red}}}}}, which apply reduction rules only to the head of the
term

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}, which are performance\sphinxhyphen{}oriented.

\end{itemize}

\sphinxAtStartPar
Conversion tactics, with two exceptions, only change the types and contexts
of existential variables
and leave the proof term unchanged.  (The {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}
tactics change existential variables in a way similar to other conversions while
also adding a single explicit cast to the proof term to tell the kernel
which reduction engine to use.  See {\hyperref[\detokenize{language/core/definitions:type-cast}]{\sphinxcrossref{\DUrole{std,std-ref}{Type cast}}}}.)  For example:
\begin{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{l+m+mi}{4} \PYG{o}{=} \PYG{l+m+mi}{7}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{4} \PYG{o}{=} \PYG{l+m+mi}{7}

\PYG{k+kn}{Show} \PYG{k+kn}{Proof}\PYG{o}{.}
    \PYG{o}{?}\PYG{k+kn}{Goal}

\PYG{k+kn}{Show} \PYG{n}{Existentials}\PYG{o}{.}
    \PYG{n}{Existential} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{:} \PYG{o}{[} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{l+m+mi}{4} \PYG{o}{=} \PYG{l+m+mi}{7}\PYG{o}{]}

\PYG{k}{cbv}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{7} \PYG{o}{=} \PYG{l+m+mi}{7}

\PYG{k+kn}{Show} \PYG{k+kn}{Proof}\PYG{o}{.}
    \PYG{o}{?}\PYG{k+kn}{Goal}

\PYG{k+kn}{Show} \PYG{n}{Existentials}\PYG{o}{.}
    \PYG{n}{Existential} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{:} \PYG{o}{[} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{7} \PYG{o}{=} \PYG{l+m+mi}{7}\PYG{o}{]}
\end{sphinxVerbatim}
\end{quote}
\index{lazy (tactic)@\spxentry{lazy}\spxextra{tactic}}\index{cbv (tactic)@\spxentry{cbv}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.lazy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lazy~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.cbv}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbv~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reduction}]{\sphinxcrossref{\DUrole{hole}{reduction}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-reduction}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reduction}]{\sphinxcrossref{\DUrole{hole}{reduction}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{beta}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{delta \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{match}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{fix}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{cofix}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{iota}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{zeta}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} {[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}\DUrole{notation-sup}{+}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Normalize the goal as specified by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}}}.  If no reductions are
specified by name, all reductions are applied.  If any reductions are specified by name,
then only the named reductions are applied.  The reductions include:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{beta}}}] \leavevmode
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/conversion:term-beta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{beta\sphinxhyphen{}reduction}}}} of functional application

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{delta \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/conversion:term-delta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{delta\sphinxhyphen{}reduction}}}}: unfolding of transparent constants, see {\hyperref[\detokenize{proofs/writing-proofs/equality:controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reduction strategies and the conversion algorithm}}}}.
The form in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}}} without the keyword \sphinxcode{\sphinxupquote{delta}} includes \sphinxcode{\sphinxupquote{beta}},
\sphinxcode{\sphinxupquote{iota}} and \sphinxcode{\sphinxupquote{zeta}} reductions in addition to \sphinxcode{\sphinxupquote{delta}} using the given \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} {[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}\DUrole{notation-sup}{+}} {]}}}}}] \leavevmode
\sphinxAtStartPar
without the \sphinxcode{\sphinxupquote{\sphinxhyphen{}}}, limits delta unfolding to the listed constants.  If the
\sphinxcode{\sphinxupquote{\sphinxhyphen{}}} is present,
unfolding is applied to all constants that are not listed.
Notice that the \sphinxcode{\sphinxupquote{delta}} doesn't apply to variables bound by a let\sphinxhyphen{}in
construction inside the term itself (use \sphinxcode{\sphinxupquote{zeta}} to inline these).
Opaque constants are never unfolded except by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}} and
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}
(see \sphinxhref{https://github.com/coq/coq/issues/4476}{\#4476}%
\begin{footnote}[29]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4476}
%
\end{footnote} and
{\hyperref[\detokenize{proofs/writing-proofs/equality:controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reduction strategies and the conversion algorithm}}}}).

\end{description}

\item[{\sphinxcode{\sphinxupquote{iota}}}] \leavevmode
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/conversion:term-iota-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{iota\sphinxhyphen{}reduction}}}} of pattern matching (\sphinxcode{\sphinxupquote{match}}) over a constructed term and reduction
of \sphinxcode{\sphinxupquote{\DUrole{keyword}{fix}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword}{cofix}}} expressions.  Shorthand for \sphinxcode{\sphinxupquote{match fix cofix}}.

\item[{\sphinxcode{\sphinxupquote{zeta}}}] \leavevmode
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/conversion:term-zeta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{zeta\sphinxhyphen{}reduction}}}}: reduction of {\hyperref[\detokenize{language/core/definitions:let-in}]{\sphinxcrossref{\DUrole{std,std-ref}{let\sphinxhyphen{}in definitions}}}}

\end{description}

\sphinxAtStartPar
Normalization is done by first evaluating the
head of the expression into \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-weak-head-normal-form}}weak\sphinxhyphen{}head normal form}, i.e. until the
evaluation is blocked by a variable, an opaque constant, an
axiom, such as in \sphinxcode{\sphinxupquote{\DUrole{notation}{x u$_{\text{1}}$ … u$_{\text{n}}$}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword}{match} \DUrole{name}{x} \DUrole{keyword}{with} \DUrole{name,builtin,pseudo}{…} \DUrole{keyword}{end}}},
\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{name,builtin,pseudo}{…}\DUrole{operator}{)} \DUrole{name}{x}}}, a constructed form (a
\(\lambda\)\sphinxhyphen{}expression, constructor, cofixpoint, inductive type,
product type or sort) or a redex for which flags prevent reduction of the redex. Once a
weak\sphinxhyphen{}head normal form is obtained, subterms are recursively reduced using the
same strategy.

\sphinxAtStartPar
There are two strategies for reduction to weak\sphinxhyphen{}head normal form:
\sphinxstyleemphasis{lazy} (the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.lazy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazy}}}}} tactic), or \sphinxstyleemphasis{call\sphinxhyphen{}by\sphinxhyphen{}value} (the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}} tactic).
The lazy strategy is a
\sphinxhref{https://en.wikipedia.org/wiki/Evaluation\_strategy\#Call\_by\_need}{call by need}%
\begin{footnote}[30]\sphinxAtStartFootnote
\sphinxnolinkurl{https://en.wikipedia.org/wiki/Evaluation\_strategy\#Call\_by\_need}
%
\end{footnote}
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.

\sphinxAtStartPar
The call\sphinxhyphen{}by\sphinxhyphen{}value strategy is the one used in ML languages: the
arguments of a function call are systematically weakly evaluated
first. The lazy strategy is similar to how Haskell reduces terms.
Although the lazy strategy always does fewer reductions than
the call\sphinxhyphen{}by\sphinxhyphen{}value strategy, the latter is generally more efficient for
evaluating purely computational expressions (i.e. with little dead code).
\index{compute (tactic)@\spxentry{compute}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.compute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{compute~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}
\sphinxAtStartPar
A variant form of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}}.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Debug}}}}} \sphinxcode{\sphinxupquote{"Cbv"}} makes {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}} (and its derivative {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{compute}}}}}) print
information about the constants it encounters and the unfolding decisions it
makes.

\end{fulllineitems}\end{savenotes}

\index{simpl (tactic)@\spxentry{simpl}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simpl~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Reduces a term to
something still readable instead of fully normalizing it. It performs
a sort of strong normalization with two key differences:
\begin{itemize}
\item {} 
\sphinxAtStartPar
It unfolds constants only if they lead to an ι\sphinxhyphen{}reduction,
i.e. reducing a match or unfolding a fixpoint.

\item {} 
\sphinxAtStartPar
When reducing a constant unfolding to (co)fixpoints, the tactic
uses the name of the constant the (co)fixpoint comes from instead of
the (co)fixpoint definition in recursive calls.

\end{itemize}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
Permits selecting whether to reduce the conclusion and/or one or more
hypotheses.  While the \sphinxcode{\sphinxupquote{at}} option of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}} is not allowed here,
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}} have a somewhat less
flexible \sphinxcode{\sphinxupquote{at}} option for selecting specific occurrences.

\end{description}

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} can unfold transparent constants whose name can be reused in
recursive calls as well as those designated by {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}} … /}}}
commands. For instance, a constant \sphinxcode{\sphinxupquote{\DUrole{name}{plus'} \DUrole{operator}{:=} \DUrole{name}{plus}}} may be unfolded and
reused in 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
not unfolded unless it was specifically designated in an {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}}
command such as \sphinxcode{\sphinxupquote{\DUrole{notation}{Arguments succ /.}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}}}} can limit the application of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}}
to:
\begin{itemize}
\item {} 
\sphinxAtStartPar
applicative subterms whose {\hyperref[\detokenize{proofs/writing-proofs/equality:term-head}]{\sphinxtermref{\DUrole{xref,std,std-term}{head}}}} is the
constant \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} or is the constant used
in the notation \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} (see \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}})

\item {} 
\sphinxAtStartPar
subterms matching a pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}

\end{itemize}

\end{fulllineitems}\end{savenotes}

\index{cbn (tactic)@\spxentry{cbn}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbn~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}} was intended to be a more principled, faster and more
predictable replacement for {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}}.

\sphinxAtStartPar
The main difference between {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} is that
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}} may unfold constants even when they cannot be reused in recursive calls:
in the previous example, \sphinxcode{\sphinxupquote{\DUrole{name}{succ} \DUrole{name}{t}}} is reduced to \sphinxcode{\sphinxupquote{\DUrole{name}{S} \DUrole{name}{t}}}.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Debug}}}}} \sphinxcode{\sphinxupquote{"RAKAM"}} makes {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}} print various debugging information.
\sphinxcode{\sphinxupquote{RAKAM}} is the Refolding Algebraic Krivine Abstract Machine.

\end{fulllineitems}\end{savenotes}

\index{hnf (tactic)@\spxentry{hnf}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{hnf~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}
\sphinxAtStartPar
Replaces the current goal with its
weak\sphinxhyphen{}head normal form according to the βδιζ\sphinxhyphen{}reduction rules, i.e. it
reduces the {\hyperref[\detokenize{proofs/writing-proofs/equality:term-head}]{\sphinxtermref{\DUrole{xref,std,std-term}{head}}}} of the goal until it becomes a product or an
irreducible term. All inner βι\sphinxhyphen{}redexes are also reduced.  While {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}}
behaves similarly to {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}}, unlike them, it does not
recurse into subterms.
The behavior of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}} can be tuned using the {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command.

\sphinxAtStartPar
Example: The term \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{n} \DUrole{operator}{:} \DUrole{name}{nat} \DUrole{operator}{=>} \DUrole{name}{S} \DUrole{name}{n} \DUrole{operator}{+} \DUrole{name}{S} \DUrole{name}{n}}} is not reduced by \sphinxcode{\sphinxupquote{\DUrole{notation}{hnf}}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The δ rule only applies to transparent constants
(see {\hyperref[\detokenize{proofs/writing-proofs/equality:controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reduction strategies and the conversion algorithm}}}} on transparency and opacity).
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{red (tactic)@\spxentry{red}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.red}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{red~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}
\sphinxAtStartPar
βιζ\sphinxhyphen{}reduces the constant at the head of \sphinxcode{\sphinxupquote{T}} (which may be called
the \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-head-constant}}head constant}; \DUrole{term-defn}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:term-head}}head} means the beginning
of the term), if possible,
in the selected hypotheses and/or the goal, which must have the form:
\begin{quote}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{forall {\hyperref[\detokenize{language/core/assumptions:grammar-token-open_binders}]{\sphinxcrossref{\DUrole{hole}{open\_binders}}}},}\DUrole{notation-sup}{?}} T}}}
\end{quote}

\sphinxAtStartPar
(where \sphinxcode{\sphinxupquote{T}} does not begin with a \sphinxcode{\sphinxupquote{forall}}) to \sphinxcode{\sphinxupquote{\DUrole{notation}{c t$_{\text{1}}$ … t$_{\text{n}}$}}}
where \sphinxcode{\sphinxupquote{\DUrole{name}{c}}} is a constant.
If \sphinxcode{\sphinxupquote{\DUrole{name}{c}}} is transparent then it replaces \sphinxcode{\sphinxupquote{\DUrole{name}{c}}} with its
definition and reduces again until no further reduction is possible.
\index{No head constant to reduce (error)@\spxentry{No head constant to reduce}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.No-head-constant-to-reduce}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~head~constant~to~reduce.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{unfold (tactic)@\spxentry{unfold}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unfold~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Applies {\hyperref[\detokenize{language/core/conversion:term-delta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{delta\sphinxhyphen{}reduction}}}} to
the constants specified by each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}}}.
The selected hypotheses and/or goals are then reduced to βιζ\sphinxhyphen{}normal form.
Use the general reduction tactics if you want to only apply the
δ rule, for example {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{delta {[} {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}} {]}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}}}}] \leavevmode
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} is a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, it must be a defined transparent
constant or local definition (see {\hyperref[\detokenize{language/core/definitions:gallina-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Top\sphinxhyphen{}level definitions}}}} and
{\hyperref[\detokenize{proofs/writing-proofs/equality:controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reduction strategies and the conversion algorithm}}}}).

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} is a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{?}}}}}, the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} is
the discriminating
symbol of a notation (e.g. "+") or an expression defining a notation (e.g. \sphinxcode{\sphinxupquote{"\_ +
\_"}}) and the notation is an application whose head symbol
is an unfoldable constant, then the tactic unfolds it.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}} is specified,
the specified occurrences will be replaced in the selected hypotheses and/or goal.
Otherwise every occurrence of the constants in the goal is replaced.
If multiple \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}}} are given, any \sphinxcode{\sphinxupquote{at}} clauses must be
in the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}}} rather than in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}}.

\end{description}
\index{Cannot turn {[}inductive\textbar{}constructor{]} into an evaluable reference (error)@\spxentry{Cannot turn {[}inductive\textbar{}constructor{]} into an evaluable reference}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Cannot-turn-_inductive|constructor_-into-an-evaluable-reference}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~turn~\DUrole{alternative}{\DUrole{alternative-block}{inductive}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{constructor}}~into~an~evaluable~reference.}}}}
\sphinxAtStartPar
Occurs when trying to unfold something that is
defined as an inductive type (or constructor) and not as a
definition.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k}{unfold} \PYG{n}{le}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{7}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{9}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{unfold} \PYG{n}{le}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}        \PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{n}{Cannot} \PYG{n}{turn} \PYG{n}{inductive} \PYG{n}{le} \PYG{n}{into} \PYG{n}{an} \PYG{n}{evaluable} \PYG{n}{reference}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{‘ident’ is opaque (error)@\spxentry{‘ident’ is opaque}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn._u2018ident_u2019-is-opaque}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~opaque.}}}}
\sphinxAtStartPar
Raised if you are trying to unfold a definition
that has been marked opaque.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Opaque} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{0} \PYG{o}{=} \PYG{l+m+mi}{1}

\PYG{k}{unfold} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add}\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}{unfold} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add}\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{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{k}{is} \PYG{n}{opaque}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Bad occurrence number of ‘qualid’ (error)@\spxentry{Bad occurrence number of ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.Bad-occurrence-number-of-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bad~occurrence~number~of~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{‘qualid’ does not occur (error)@\spxentry{‘qualid’ does not occur}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn._u2018qualid_u2019-does-not-occur}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~does~not~occur.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{fold (tactic)@\spxentry{fold}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.fold}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fold~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}
\sphinxAtStartPar
First, this tactic reduces each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} using the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.red}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{red}}}}} tactic.
Then, every occurrence of the resulting terms in the selected hypotheses and/or
goal will be replaced by its associated \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}. This tactic is particularly
useful for
reversing undesired unfoldings, which may make the goal very hard to read.
The undesired unfoldings may be due to the limited capabilities of
other reduction tactics.
On the other hand, when an unfolded function applied to its argument has been
reduced, the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.fold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fold}}}}} tactic doesn't do anything.

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.fold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fold}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{2}}$}}}}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{fold {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{1}}$}}}}; fold {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{2}}$}}}}}}}.

\begin{sphinxadmonition}{note}{Example: \sphinxstyleliteralintitle{\sphinxupquote{fold}} doesn't always undo \sphinxstyleliteralintitle{\sphinxupquote{unfold}}}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{o}{\PYGZti{}}\PYG{l+m+mi}{0}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{l+m+mi}{0}

\PYG{k}{unfold} \PYG{n}{not}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}
\end{sphinxVerbatim}

\sphinxAtStartPar
This {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.fold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fold}}}}} doesn't undo the preceeding {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}} (it makes no change):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{fold} \PYG{n}{not}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}
\end{sphinxVerbatim}

\sphinxAtStartPar
However, this {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} followed by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.fold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fold}}}}} does:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pattern} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{P} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{=\PYGZgt{}} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}\PYG{o}{)} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)}

\PYG{k}{fold} \PYG{n}{not}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{l+m+mi}{0}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: Use \sphinxstyleliteralintitle{\sphinxupquote{fold}} to reverse unfolding of \sphinxstyleliteralintitle{\sphinxupquote{fold\_right}}}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{xs}\PYG{o}{,} \PYG{n}{fold\PYGZus{}right} \PYG{n}{and} \PYG{n}{True} \PYG{o}{(}\PYG{n}{x}\PYG{o}{::}\PYG{n}{xs}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{xs} \PYG{o}{:} \PYG{n}{list} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,} \PYG{n}{fold\PYGZus{}right} \PYG{n}{and} \PYG{n}{True} \PYG{o}{(}\PYG{n}{x} \PYG{o}{::} \PYG{n}{xs}\PYG{o}{)}

\PYG{k}{red}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{xs} \PYG{o}{:} \PYG{n}{list} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{x} \PYG{o}{/\PYGZbs{}}
      \PYG{o}{(}\PYG{k}{fix} \PYG{n}{fold\PYGZus{}right} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
         \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
         \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{|} \PYG{n}{b} \PYG{o}{::} \PYG{n}{t} \PYG{o}{=\PYGZgt{}} \PYG{n}{b} \PYG{o}{/\PYGZbs{}} \PYG{n}{fold\PYGZus{}right} \PYG{n}{t}
         \PYG{k}{end}\PYG{o}{)} \PYG{n}{xs}

\PYG{k}{fold} \PYG{o}{(}\PYG{n}{fold\PYGZus{}right} \PYG{n}{and} \PYG{n}{True}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{xs} \PYG{o}{:} \PYG{n}{list} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x} \PYG{o}{/\PYGZbs{}} \PYG{n}{fold\PYGZus{}right} \PYG{n}{and} \PYG{n}{True} \PYG{n}{xs}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{pattern (tactic)@\spxentry{pattern}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.pattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pattern~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Performs beta\sphinxhyphen{}expansion (the inverse of {\hyperref[\detokenize{language/core/conversion:term-beta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{beta\sphinxhyphen{}reduction}}}}) for the
selected hypotheses and/or goals.
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}s in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}} must be free subterms in the selected items.
The expansion is done for each selected item \sphinxcode{\sphinxupquote{\DUrole{name}{T}}}
for a set of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}s in the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}} by:
\begin{itemize}
\item {} 
\sphinxAtStartPar
replacing all selected occurrences of the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}s in \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} with fresh variables

\item {} 
\sphinxAtStartPar
abstracting these variables

\item {} 
\sphinxAtStartPar
applying the abstracted goal to the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}s

\end{itemize}

\sphinxAtStartPar
For instance, if the current goal \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} is expressible as \sphinxcode{\sphinxupquote{\DUrole{notation}{φ(t$_{\text{1}}$ … t$_{\text{n}}$)}}}
where the notation captures all the instances of the \sphinxcode{\sphinxupquote{\DUrole{notation}{t$_{\text{i}}$}}} in φ, then {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{t$_{\text{1}}$, …, t$_{\text{n}}$}}} generates the equivalent goal
\sphinxcode{\sphinxupquote{\DUrole{notation}{(fun (x$_{\text{1}}$:A$_{\text{1}}$ … (x$_{\text{n}}$:A$_{\text{n}}$) => φ(x$_{\text{1}}$ … x$_{\text{n}}$)) t$_{\text{1}}$ … t$_{\text{n}}$}}}.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{t$_{\text{i}}$}}} occurs in one of the generated types \sphinxcode{\sphinxupquote{\DUrole{notation}{A$_{\text{j}}$}}}
(for \sphinxcode{\sphinxupquote{j > i}}),
occurrences will also be considered and possibly abstracted.

\sphinxAtStartPar
This tactic can be used, for instance, when the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} fails
on matching or to better control the behavior of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Fast reduction tactics: vm\_compute and native\_compute}
\label{\detokenize{proofs/writing-proofs/equality:fast-reduction-tactics-vm-compute-and-native-compute}}
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}} is a brute\sphinxhyphen{}force but efficient tactic that
first normalizes the terms before comparing them. It is based on a
bytecode representation of terms similar to the bytecode
representation used in the ZINC virtual machine {[}\hyperlink{cite.zebibliography:id31}{Ler90}{]}. It is
especially useful for intensive computation of algebraic values, such
as numbers, and for reflection\sphinxhyphen{}based tactics.

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} is based on on converting the Coq code to OCaml.

\sphinxAtStartPar
Note that both these tactics ignore {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} markings
(see issue \sphinxhref{https://github.com/coq/coq/issues/4776}{\#4776}%
\begin{footnote}[31]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4776}
%
\end{footnote}), nor do they
apply unfolding strategies such as from {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Strategy}}}}}.

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} is typically two to five
times faster than {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}} at applying conversion rules
when Coq is running native code, but {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} requires
considerably more overhead.  We recommend using {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}
when all of the following are true (otherwise use {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}}):
\begin{itemize}
\item {} 
\sphinxAtStartPar
the running time in {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}} at least 5\sphinxhyphen{}10 seconds

\item {} 
\sphinxAtStartPar
the size of the input term is small (e.g. hand\sphinxhyphen{}generated code rather than
automatically\sphinxhyphen{}generated code that may have nested destructs on inductives
with dozens or hundreds of constructors)

\item {} 
\sphinxAtStartPar
the output is small (e.g. you're returning a boolean, a natural number or
an integer rather than a large abstract syntax tree)

\end{itemize}

\sphinxAtStartPar
These tactics change existential variables in a way similar to other conversions
while also adding a single explicit cast (see {\hyperref[\detokenize{language/core/definitions:type-cast}]{\sphinxcrossref{\DUrole{std,std-ref}{Type cast}}}}) to the proof term
to tell the kernel which reduction engine to use.
\index{vm\_compute (tactic)@\spxentry{vm\_compute}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{vm\_compute~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Evaluates the goal using the optimized call\sphinxhyphen{}by\sphinxhyphen{}value evaluation
bytecode\sphinxhyphen{}based virtual machine described in {[}\hyperlink{cite.zebibliography:id52}{GregoireL02}{]}.
This algorithm is dramatically more efficient than the algorithm used for the
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}} tactic, but it cannot be fine\sphinxhyphen{}tuned. It is especially useful for
full evaluation of algebraic objects. This includes the case of
reflection\sphinxhyphen{}based tactics.

\end{fulllineitems}\end{savenotes}

\index{native\_compute (tactic)@\spxentry{native\_compute}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{native\_compute~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Evaluates the goal by compilation to OCaml as described
in {[}\hyperlink{cite.zebibliography:id53}{BDenesGregoire11}{]}. Depending on the configuration, this tactic can either default to
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}}, recompile dependencies or fail due to some missing
precompiled dependencies,
see {\hyperref[\detokenize{practical-tools/coq-commands:native-compiler-options}]{\sphinxcrossref{\DUrole{std,std-ref}{the native\sphinxhyphen{}compiler option}}}} for details.
\index{NativeCompute Timing (flag)@\spxentry{NativeCompute Timing}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:flag.NativeCompute-Timing}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{NativeCompute~Timing}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} causes all calls to the native compiler to print
timing information for the conversion to native code,
compilation, execution, and reification phases of native
compilation.  Timing is printed in units of seconds of
wall\sphinxhyphen{}clock time.

\end{fulllineitems}\end{savenotes}

\index{NativeCompute Profiling (flag)@\spxentry{NativeCompute Profiling}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:flag.NativeCompute-Profiling}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{NativeCompute~Profiling}}}}
\sphinxAtStartPar
On Linux, if you have the \sphinxcode{\sphinxupquote{perf}} profiler installed, this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} makes
it possible to profile {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} evaluations.

\end{fulllineitems}\end{savenotes}

\index{NativeCompute Profile Filename (option)@\spxentry{NativeCompute Profile Filename}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:opt.NativeCompute-Profile-Filename}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{NativeCompute~Profile~Filename~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{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
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\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{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Computing in a term: eval and Eval}
\label{\detokenize{proofs/writing-proofs/equality:computing-in-a-term-eval-and-eval}}
\sphinxAtStartPar
Evaluation of a term can be performed with:
\index{eval (tactic)@\spxentry{eval}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.eval}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eval~{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}~in~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{lazy \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{cbv \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{compute \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{vm\_compute \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{native\_compute \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{red}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{hnf}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{simpl \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\DUrole{hole}{delta\_reductions}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{cbn \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\DUrole{hole}{reductions}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{unfold \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reference_occs}]{\sphinxcrossref{\DUrole{hole}{reference\_occs}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{fold \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{pattern \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-pattern_occs}]{\sphinxcrossref{\DUrole{hole}{pattern\_occs}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eval}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-value_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{value\_tactic}}}}}.  It returns the result of
applying the conversion rules specified by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}}}}.  It does not
change the proof state.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}}}} alternatives that begin with a keyword correspond to the
tactic with the same name, though in several cases with simpler syntax
than the tactic.  \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a named reduction expression created
with {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Declare-Reduction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare Reduction}}}}}.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
Section {\hyperref[\detokenize{proofs/writing-proofs/equality:applyingconversionrules}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying conversion rules}}}}.



\end{fulllineitems}\end{savenotes}

\index{Eval (command)@\spxentry{Eval}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Eval}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Eval~{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}~in~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
Performs the specified reduction on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and displays
the resulting term with its type. If a proof is open, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
may reference hypotheses of the selected goal.  {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Eval}}}}} is
a {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-query_command}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{query\_command}}}}}, so it may be prefixed with a goal selector.
\index{Compute (command)@\spxentry{Compute}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Compute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Compute~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
Evaluates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} using the bytecode\sphinxhyphen{}based virtual machine.
It is a shortcut for {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Eval}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{vm\_compute in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Compute}}}}} is a {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-query_command}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{query\_command}}}}}, so it may be prefixed
with a goal selector.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Declare Reduction (command)@\spxentry{Declare Reduction}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Declare-Reduction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Reduction~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}}}}}
\sphinxAtStartPar
Declares a short name for the reduction expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}}}}, for
instance \sphinxcode{\sphinxupquote{lazy beta delta {[}foo bar{]}}}. This short name can then be used
in \sphinxcode{\sphinxupquote{\DUrole{notation}{Eval {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in}}} or \sphinxcode{\sphinxupquote{eval}} constructs. This command
accepts the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which indicates that the reduction
will be discarded at the end of the
file or module. The name is not qualified. In
particular declaring the same name in several modules or in several
functor applications will be rejected if these declarations are not
local. The name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} cannot be used directly as an Ltac tactic, but
nothing prevents the user from also performing a
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}}}}.

\end{fulllineitems}\end{savenotes}



\subsubsection{Controlling reduction strategies and the conversion algorithm}
\label{\detokenize{proofs/writing-proofs/equality:controlling-reduction-strategies-and-the-conversion-algorithm}}\label{\detokenize{proofs/writing-proofs/equality:controlling-the-reduction-strategies}}
\sphinxAtStartPar
The commands to fine\sphinxhyphen{}tune the reduction strategies and the lazy conversion
algorithm are described in this section.  Also see {\hyperref[\detokenize{language/extensions/arguments-command:args-effect-on-unfolding}]{\sphinxcrossref{\DUrole{std,std-ref}{Effects of Arguments on unfolding}}}},
which supports additional fine\sphinxhyphen{}tuning.
\index{Opaque (command)@\spxentry{Opaque}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Opaque~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Marks the specified constants as {\hyperref[\detokenize{language/core/conversion:term-opaque}]{\sphinxtermref{\DUrole{xref,std,std-term}{opaque}}}} so tactics won't {\hyperref[\detokenize{language/core/conversion:term-unfold}]{\sphinxtermref{\DUrole{xref,std,std-term}{unfold}}}} them
with {\hyperref[\detokenize{language/core/conversion:term-delta-reduction}]{\sphinxtermref{\DUrole{xref,std,std-term}{delta\sphinxhyphen{}reduction}}}}.
"Constants" are items defined by commands such as {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}},
{\hyperref[\detokenize{language/core/sections:coq:cmd.Let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let}}}}} (with an explicit body), {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}, {\hyperref[\detokenize{language/core/coinductive:coq:cmd.CoFixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}}
and {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}.

\sphinxAtStartPar
This command accepts the {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attribute.  By default, the scope
of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} is limited to the current section or module.

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} also affects Coq's conversion algorithm, causing
it to delay unfolding the specified constants as much as possible when it
has to check that two distinct applied constants are convertible.
See Section {\hyperref[\detokenize{language/core/conversion:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}}.

\end{fulllineitems}\end{savenotes}

\index{Transparent (command)@\spxentry{Transparent}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Transparent}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Transparent~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
The opposite of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}, it marks the specified constants
as {\hyperref[\detokenize{language/core/conversion:term-transparent}]{\sphinxtermref{\DUrole{xref,std,std-term}{transparent}}}}
so that tactics may unfold them.  See {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} above.

\sphinxAtStartPar
This command accepts the {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attribute.  By default, the scope
of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}} is limited to the current section or module.

\sphinxAtStartPar
Note that constants defined by proofs ending with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} are
irreversibly opaque; {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}} will not make them transparent.
This is consistent
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{The reference ‘qualid’ was not found in the current environment (error)@\spxentry{The reference ‘qualid’ was not found in the current environment}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.The-reference-_u2018qualid_u2019-was-not-found-in-the-current-environment}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~reference~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~was~not~found~in~the~current~environment.}}}}
\sphinxAtStartPar
There is no constant named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} in the environment.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:applyingconversionrules}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying conversion rules}}}}, {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}


\phantomsection\label{\detokenize{proofs/writing-proofs/equality:vernac-strategy}}\index{Strategy (command)@\spxentry{Strategy}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Strategy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Strategy~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level}]{\sphinxcrossref{\DUrole{hole}{strategy\_level}}}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}\DUrole{notation-sup}{+}}~{]}}\DUrole{notation-sup}{+}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level}]{\sphinxcrossref{\DUrole{hole}{strategy\_level}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{opaque}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{expand}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{transparent}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Generalizes the behavior of the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}}
commands. It is used to fine\sphinxhyphen{}tune the strategy for unfolding
constants, both at the tactic level and at the kernel level. This
command associates a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level}]{\sphinxcrossref{\DUrole{hole}{strategy\_level}}}}}}} with the qualified names in the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}
sequence. Whenever two
expressions with two distinct head constants are compared (for
example, typechecking \sphinxcode{\sphinxupquote{f x}} where \sphinxcode{\sphinxupquote{f : A \sphinxhyphen{}> B}} and \sphinxcode{\sphinxupquote{x : C}} will result in
converting \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{C}}), the one
with lower level is expanded first. In case of a tie, the second one
(appearing in the cast type) is expanded.

\sphinxAtStartPar
This command accepts the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute, which limits its effect
to the current section or module, in which case the section and module
behavior is the same as {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}} (without {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}}).

\sphinxAtStartPar
Levels can be one of the following (higher to lower):
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{opaque}} : level of opaque constants. They cannot be expanded by
tactics (behaves like +∞, see next item).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}} : 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 \sphinxcode{\sphinxupquote{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 {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{expand}} : level of constants that should be expanded first (behaves
like −∞)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{transparent}} : Equivalent to level 0

\end{itemize}

\end{fulllineitems}\end{savenotes}

\index{Print Strategy (command)@\spxentry{Print Strategy}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Print-Strategy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Strategy~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}
\sphinxAtStartPar
This command prints the strategy currently associated with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}. It
fails if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} is not an unfoldable reference, that is, neither a
variable nor a constant.
\index{The reference is not unfoldable (error)@\spxentry{The reference is not unfoldable}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:exn.The-reference-is-not-unfoldable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~reference~is~not~unfoldable.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Print Strategies (command)@\spxentry{Print Strategies}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:cmd.Print-Strategies}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Strategies}}}}
\sphinxAtStartPar
Print all the currently non\sphinxhyphen{}transparent strategies.

\end{fulllineitems}\end{savenotes}

\index{with\_strategy (tactic)@\spxentry{with\_strategy}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/equality:coq:tacn.with_strategy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{with\_strategy~{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level_or_var}]{\sphinxcrossref{\DUrole{hole}{strategy\_level\_or\_var}}}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}\DUrole{notation-sup}{+}}~{]}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level_or_var}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level_or_var}]{\sphinxcrossref{\DUrole{hole}{strategy\_level\_or\_var}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-strategy_level}]{\sphinxcrossref{\DUrole{hole}{strategy\_level}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Executes {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}}, applying the alternate unfolding
behavior that the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Strategy}}}}} command controls, but only for
{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}}.  This can be useful for guarding calls to
reduction in tactic automation to ensure that certain constants are
never unfolded by tactics like {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}} or to
ensure that unfolding does not fail.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Opaque} \PYG{n}{id}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{id} \PYG{l+m+mi}{10} \PYG{o}{=} \PYG{l+m+mi}{10}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{id} \PYG{l+m+mi}{10} \PYG{o}{=} \PYG{l+m+mi}{10}

\PYG{n}{Fail} \PYG{k}{unfold} \PYG{n}{id}\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}{id} \PYG{k}{is} \PYG{n}{opaque}\PYG{o}{.}

\PYG{n}{with\PYGZus{}strategy} \PYG{n}{transparent} \PYG{o}{[}\PYG{n}{id}\PYG{o}{]} \PYG{k}{unfold} \PYG{n}{id}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{10} \PYG{o}{=} \PYG{l+m+mi}{10}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
Use this tactic with care, as effects do not persist past the
end of the proof script.  Notably, this fine\sphinxhyphen{}tuning of the
conversion strategy is not in effect during {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} nor
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}, so this tactic is most useful either in
combination with {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}}, which will check the proof
early while the fine\sphinxhyphen{}tuning is still in effect, or to guard
calls to conversion in tactic automation to ensure that, e.g.,
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}} does not fail just because the user made a
constant {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}.

\sphinxAtStartPar
This can be illustrated with the following example involving the
factorial function.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{fact} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{1}
  \PYG{o}{|} \PYG{n}{S} \PYG{n}{n\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{n} \PYG{o}{*} \PYG{n}{fact} \PYG{n}{n\PYGZsq{}}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Suppose now that, for whatever reason, we want in general to
unfold the \sphinxcode{\sphinxupquote{\DUrole{name}{id}}} function very late during conversion:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Strategy} \PYG{l+m+mi}{1000} \PYG{o}{[}\PYG{n}{id}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
If we try to prove \sphinxcode{\sphinxupquote{\DUrole{name}{id} \DUrole{operator}{(}\DUrole{name}{fact} \DUrole{name}{n}\DUrole{operator}{)} \DUrole{operator}{=} \DUrole{name}{fact} \DUrole{name}{n}}} by
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}}, it will now take time proportional to
\(n!\), because Coq will keep unfolding \sphinxcode{\sphinxupquote{\DUrole{name}{fact}}} and
\sphinxcode{\sphinxupquote{\DUrole{operator}{*}}} and \sphinxcode{\sphinxupquote{\DUrole{operator}{+}}} before it unfolds \sphinxcode{\sphinxupquote{\DUrole{name}{id}}}, resulting in a full
computation of \sphinxcode{\sphinxupquote{\DUrole{name}{fact} \DUrole{name}{n}}} (in unary, because we are using
\sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}), which takes time \(n!\).  We can see this cross
the relevant threshold at around \(n = 9\):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Time} \PYG{k}{assert} \PYG{o}{(}\PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{8}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{8}\PYG{o}{)} \PYG{k+kp}{by} \PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{n}{Finished} \PYG{n}{transaction} \PYG{k}{in} \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{507} \PYG{n}{secs} \PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{372}\PYG{n}{u}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{131}\PYG{n}{s}\PYG{o}{)} \PYG{o}{(}\PYG{n}{successful}\PYG{o}{)}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{8}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{8}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Time} \PYG{k}{assert} \PYG{o}{(}\PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{9}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{9}\PYG{o}{)} \PYG{k+kp}{by} \PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{n}{Finished} \PYG{n}{transaction} \PYG{k}{in} \PYG{l+m+mi}{2}\PYG{o}{.}\PYG{l+m+mi}{951} \PYG{n}{secs} \PYG{o}{(}\PYG{l+m+mi}{2}\PYG{o}{.}\PYG{l+m+mi}{923}\PYG{n}{u}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{003}\PYG{n}{s}\PYG{o}{)} \PYG{o}{(}\PYG{n}{successful}\PYG{o}{)}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{8}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{8}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{9}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{9}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\sphinxAtStartPar
Note that behavior will be the same if you mark \sphinxcode{\sphinxupquote{\DUrole{name}{id}}} as
\sphinxcode{\sphinxupquote{\DUrole{name}{Opaque}}} because while most reduction tactics refuse to
unfold \sphinxcode{\sphinxupquote{\DUrole{name}{Opaque}}} constants, conversion treats \sphinxcode{\sphinxupquote{\DUrole{name}{Opaque}}} as
merely a hint to unfold this constant last.

\sphinxAtStartPar
We can get around this issue by using {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.with_strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{with\_strategy}}}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Fail} \PYG{n}{Timeout} \PYG{l+m+mi}{1} \PYG{k}{assert} \PYG{o}{(}\PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{k+kp}{by} \PYG{k+kp}{reflexivity}\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}{Timeout}\PYG{o}{!}

\PYG{n}{Time} \PYG{k}{assert} \PYG{o}{(}\PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{k+kp}{by} \PYG{n}{with\PYGZus{}strategy} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1} \PYG{o}{[}\PYG{n}{id}\PYG{o}{]} \PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{n}{Finished} \PYG{n}{transaction} \PYG{k}{in} \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{003} \PYG{n}{secs} \PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{003}\PYG{n}{u}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{s}\PYG{o}{)} \PYG{o}{(}\PYG{n}{successful}\PYG{o}{)}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{100}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\sphinxAtStartPar
However, when we go to close the proof, we will run into
trouble, because the reduction strategy changes are local to the
tactic passed to {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.with_strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{with\_strategy}}}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{exact} \PYG{n}{I}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{n}{Timeout} \PYG{l+m+mi}{1} \PYG{k+kn}{Defined}\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}{18}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{Timeout} \PYG{l+m+mi}{1} \PYG{k+kn}{Defined}\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{n}{Error}\PYG{o}{:} \PYG{n}{Timeout}\PYG{o}{!}
\end{sphinxVerbatim}

\sphinxAtStartPar
We can fix this issue by using {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Time} \PYG{k}{assert} \PYG{o}{(}\PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{k+kp}{by} \PYG{n}{with\PYGZus{}strategy} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1} \PYG{o}{[}\PYG{n}{id}\PYG{o}{]} \PYG{n}{abstract} \PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{n}{Finished} \PYG{n}{transaction} \PYG{k}{in} \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{006} \PYG{n}{secs} \PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{006}\PYG{n}{u}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{s}\PYG{o}{)} \PYG{o}{(}\PYG{n}{successful}\PYG{o}{)}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{id} \PYG{o}{(}\PYG{n}{fact} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{o}{=} \PYG{n}{fact} \PYG{l+m+mi}{100}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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+kp}{exact} \PYG{n}{I}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{n}{Time} \PYG{k+kn}{Defined}\PYG{o}{.}
    \PYG{n}{Finished} \PYG{n}{transaction} \PYG{k}{in} \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{003} \PYG{n}{secs} \PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{003}\PYG{n}{u}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{s}\PYG{o}{)} \PYG{o}{(}\PYG{n}{successful}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
On small examples this sort of behavior doesn't matter, but
because Coq is a super\sphinxhyphen{}linear performance domain in so many
places, unless great care is taken, tactic automation using
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.with_strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{with\_strategy}}}}} may not be robustly performant when
scaling the size of the input.
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
In much the same way this tactic does not play well with
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}} without using {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}} as
an intermediary, this tactic does not play well with \sphinxcode{\sphinxupquote{coqchk}},
even when used with {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}}, due to the inability of
tactics to persist information about conversion hints in the
proof term. See \sphinxhref{https://github.com/coq/coq/issues/12200}{\#12200}%
\begin{footnote}[32]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12200}
%
\end{footnote} for more details.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\subsection{Reasoning with inductive types}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:reasoning-with-inductive-types}}\label{\detokenize{proofs/writing-proofs/reasoning-inductives::doc}}

\subsubsection{Applying constructors}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:applying-constructors}}
\sphinxAtStartPar
The tactics presented here specialize {\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}}}}}) to the case of constructors of inductive types.
\index{constructor (tactic)@\spxentry{constructor}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.constructor}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{constructor~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} 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\sphinxhyphen{}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 (error)@\spxentry{Not an inductive product}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.Not-an-inductive-product}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~an~inductive~product.}}}}
\end{fulllineitems}\end{savenotes}

\index{Not enough constructors (error)@\spxentry{Not enough constructors}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.Not-enough-constructors}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~enough~constructors.}}}}
\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{constructor}}}}
\sphinxAtStartPar
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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{constructor~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
Let \sphinxcode{\sphinxupquote{c}} be the i\sphinxhyphen{}th constructor of \sphinxcode{\sphinxupquote{\DUrole{name}{I}}}, then
\sphinxcode{\sphinxupquote{\DUrole{notation}{constructor i with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros; apply c with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The terms in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bindings}}}}} 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}\end{savenotes}

\index{split (tactic variant)@\spxentry{split}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives: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}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
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}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}. It is
typically used in the case of a conjunction \(A \wedge B\).
\index{exists (tactic variant)@\spxentry{exists}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.exists}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exists~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
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}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}.}}} It is typically used in
the case of an existential quantification \(\exists x, P(x).\)

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exists~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This iteratively applies \sphinxcode{\sphinxupquote{\DUrole{notation}{exists {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Not an inductive goal with 1 constructor (error)@\spxentry{Not an inductive goal with 1 constructor}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives: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{savenotes}


\end{fulllineitems}\end{savenotes}

\index{left (tactic variant)@\spxentry{left}\spxextra{tactic variant}}\index{right (tactic variant)@\spxentry{right}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives: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}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives: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}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
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}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{constructor 2 \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}.
\index{Not an inductive goal with 2 constructors (error)@\spxentry{Not an inductive goal with 2 constructors}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives: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{savenotes}


\end{fulllineitems}\end{savenotes}

\index{econstructor (tactic variant)@\spxentry{econstructor}\spxextra{tactic variant}}\index{eexists (tactic variant)@\spxentry{eexists}\spxextra{tactic variant}}\index{esplit (tactic variant)@\spxentry{esplit}\spxextra{tactic variant}}\index{eleft (tactic variant)@\spxentry{eleft}\spxextra{tactic variant}}\index{eright (tactic variant)@\spxentry{eright}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.econstructor}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{econstructor}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.eexists}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eexists}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.esplit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{esplit}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.eleft}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eleft}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.eright}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eright}}}}
\sphinxAtStartPar
These tactics and their variants behave like {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.constructor}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{constructor}}}}},
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.exists}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exists}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.split}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{split}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.left}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{left}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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{savenotes}


\end{fulllineitems}\end{savenotes}



\subsubsection{Case analysis and induction}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:case-analysis-and-induction}}\label{\detokenize{proofs/writing-proofs/reasoning-inductives:caseanalysisandinduction}}
\sphinxAtStartPar
The tactics presented in this section implement induction or case
analysis on inductive or co\sphinxhyphen{}inductive objects (see {\hyperref[\detokenize{language/core/inductive:inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Theory of inductive definitions}}}}).
\index{destruct (tactic)@\spxentry{destruct}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic applies to any goal. The argument {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} must be of
inductive or co\sphinxhyphen{}inductive type and the tactic generates subgoals, one
for each possible form of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, i.e. one for each constructor of the
inductive or co\sphinxhyphen{}inductive type. Unlike {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}, no induction
hypothesis is generated by {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}.


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
If {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} behaves
as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; destruct {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. If {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is not
anymore dependent in the goal after application of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}).

\sphinxAtStartPar
If {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a hypothesis of the context, and {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
is not anymore dependent in the goal after application
of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}).

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}~\begin{quote}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}
followed by destruct applied to the last introduced hypothesis.
\end{quote}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
For destruction of a number, use syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct ({\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}})}}} (not
very interesting anyway).
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}}}
\sphinxAtStartPar
The argument of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This is a shortcut for \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}; ...; destruct {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}}
\sphinxAtStartPar
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but uses the names
in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{or\_and\_intropattern\_loc}}}}} to name the variables introduced in the
context. The {\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{or\_and\_intropattern\_loc}}}}} must have the
form \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}p11 ... p1n | ... | pm1 ... pmn {]}}}} with \sphinxcode{\sphinxupquote{m}} being the
number of constructors of the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. Each variable
introduced by {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} in the context of the \sphinxcode{\sphinxupquote{i}}\sphinxhyphen{}th goal
gets its name from the list \sphinxcode{\sphinxupquote{\DUrole{notation}{pi1 ... pin}}} in order. If there are not
enough names, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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}\end{savenotes}

\index{destruct … eqn: (tactic variant)@\spxentry{destruct … eqn:}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.destruct-_u2026-eqn:}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~eqn:{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}}}}
\sphinxAtStartPar
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but adds an equation
between {\hyperref[\detokenize{language/core/basic: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 {\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{naming\_intropattern}}}}} (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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} providing explicit instances for
the dependent premises of the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\end{fulllineitems}\end{savenotes}

\index{edestruct (tactic variant)@\spxentry{edestruct}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.edestruct}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{edestruct~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/core/basic: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/core/basic: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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This is synonym of \sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} using {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
\sphinxAtStartPar
This syntax is used for selecting which occurrences of {\hyperref[\detokenize{language/core/basic: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:occurrencessets}]{\sphinxcrossref{\DUrole{std,std-ref}{occurrences sets}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:{\hyperref[\detokenize{proof-engine/tactics:grammar-token-naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{naming\_intropattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\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}{?}}}}}}
\sphinxAtStartPar
These are the general forms of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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{savenotes}


\end{fulllineitems}\end{savenotes}

\index{case (tactic)@\spxentry{case}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.case}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{case~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but using a case\sphinxhyphen{}analysis
elimination principle and not a recursive one.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{case~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
Analogous to \sphinxcode{\sphinxupquote{\DUrole{notation}{elim {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}} above.

\end{fulllineitems}\end{savenotes}

\index{ecase (tactic variant)@\spxentry{ecase}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.ecase}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ecase~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
In case the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}} clause,
\sphinxcode{\sphinxupquote{\DUrole{notation}{ecase}}} turns them into existential variables to be resolved later on.

\end{fulllineitems}\end{savenotes}

\index{simple destruct (tactic variant)@\spxentry{simple destruct}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.simple-destruct}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; case {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
is a quantified variable of the goal.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~destruct~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}; case {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
is the name given by \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} to the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} \sphinxhyphen{}th
non\sphinxhyphen{}dependent premise of the goal.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{case\_eq~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{induction (tactic)@\spxentry{induction}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic applies to any goal. The argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, i.e. one for each constructor of the
inductive type.

\sphinxAtStartPar
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}.

\sphinxAtStartPar
There are particular cases:
\begin{itemize}
\item {} 
\sphinxAtStartPar
If term is an identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; induction {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}).

\item {} 
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}, then \sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} followed by \sphinxcode{\sphinxupquote{\DUrole{notation}{induction}}} applied to the last
introduced hypothesis.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
For simple induction on a number, use syntax induction (number)
(not very interesting anyway).
\end{sphinxadmonition}

\item {} 
\sphinxAtStartPar
In case term is a hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} of the context, and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}).

\item {} 
\sphinxAtStartPar
The argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{induction\PYGZus{}test} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \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}{goal} \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}

\PYG{k+kp}{exact} \PYG{o}{(}\PYG{n}{le\PYGZus{}n} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{S} \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n}
      \PYG{n}{IHn} \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{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{n}{n}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Not an inductive product (error)@\spxentry{Not an inductive product}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:id1}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~an~inductive~product.}}}}
\end{fulllineitems}\end{savenotes}

\index{Unable to find an instance for the variables ‘ident’ ... ‘ident’ (error)@\spxentry{Unable to find an instance for the variables ‘ident’ ... ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.Unable-to-find-an-instance-for-the-variables-_u2018ident_u2019-...-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~find~an~instance~for~the~variables~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~...~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\sphinxAtStartPar
Use in this case the variant {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.elim-_u2026-with}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim … with}}}}} below.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}}
\sphinxAtStartPar
This behaves as {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} but uses the names in
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}} to name the variables introduced in the
context. The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}} must typically be of the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} p}}} $_{\text{11}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}} $_{\text{1n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{| ... | 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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. Each
variable introduced by induction in the context of the i\sphinxhyphen{}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-_u2026}]{\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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
This behaves like {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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:bindings}]{\sphinxcrossref{\DUrole{std,std-ref}{Bindings}}}}).

\end{fulllineitems}\end{savenotes}

\index{einduction (tactic variant)@\spxentry{einduction}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.einduction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einduction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic behaves like {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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/core/basic: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}\end{savenotes}

\index{induction … using … (tactic variant)@\spxentry{induction … using …}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.induction-_u2026-using-_u2026}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This behaves as {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}  but using \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to be
inductive.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
This behaves as {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.induction-_u2026-using-_u2026}]{\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~using~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
This syntax is used for the case \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules: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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
\sphinxAtStartPar
This syntax is used for selecting which occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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:occurrencessets}]{\sphinxcrossref{\DUrole{std,std-ref}{occurrences sets}}}}. If variables or hypotheses not
mentioning \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{\PYGZhy{}}   \PYG{o}{*}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{goal} \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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{IHy} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einduction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
\sphinxAtStartPar
These are the most general forms of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.einduction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{einduction}}}}}. It combines the
effects of the with, as, using, and in clauses.

\end{fulllineitems}\end{savenotes}

\index{elim (tactic variant)@\spxentry{elim}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.elim}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This is a more basic induction tactic. Again, the type of the argument
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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 local context
contains \sphinxcode{\sphinxupquote{\DUrole{name}{n}\DUrole{operator}{:}\DUrole{name}{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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} also works when the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and leaves the
non\sphinxhyphen{}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}\end{savenotes}

\index{elim … with (tactic variant)@\spxentry{elim … with}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.elim-_u2026-with}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
Allows to give explicit instances to the premises of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
(see {\hyperref[\detokenize{proof-engine/tactics:bindings}]{\sphinxcrossref{\DUrole{std,std-ref}{Bindings}}}}).

\end{fulllineitems}\end{savenotes}

\index{eelim (tactic variant)@\spxentry{eelim}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.eelim}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eelim~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
In case the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} has dependent premises, this turns them into
existential variables to be resolved later on.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
Allows the user to give explicitly an induction principle \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. The
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}} clause allows instantiating premises of the type of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eelim~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
These are the most general forms of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.elim}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.eelim}]{\sphinxcrossref{\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}\end{savenotes}

\index{elimtype (tactic variant)@\spxentry{elimtype}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.elimtype}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elimtype~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
\sphinxAtStartPar
The argument {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} 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/core/basic: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}\end{savenotes}

\index{simple induction (tactic variant)@\spxentry{simple induction}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.simple-induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~induction~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; elim {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} when
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a quantified variable of the goal.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~induction~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}; elim {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
is the name given by \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} to the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}\sphinxhyphen{}th non\sphinxhyphen{}dependent
premise of the goal.

\end{fulllineitems}\end{savenotes}

\index{dependent induction (tactic)@\spxentry{dependent induction}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.dependent-induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~induction~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
The \sphinxstyleemphasis{experimental} tactic dependent induction performs induction\sphinxhyphen{}
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
{[}\hyperlink{cite.zebibliography:id36}{McB00}{]} and the work of Cristina Cornes around
inversion {[}\hyperlink{cite.zebibliography:id13}{CT95}{]}. 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}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{lt\PYGZus{}1\PYGZus{}r} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goals}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\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}{lt\PYGZus{}1\PYGZus{}r} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Now we are in a contradictory context and the proof can be solved.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{inversion} \PYG{n}{H}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~induction~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~generalizing~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This performs dependent induction on the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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}\end{savenotes}

\index{dependent destruction (tactic variant)@\spxentry{dependent destruction}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.dependent-destruction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~destruction~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This performs the generalization of the instance \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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}\end{savenotes}


\sphinxAtStartPar
See also the larger example of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.dependent-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dependent induction}}}}}
and an explanation of the underlying technique.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{using/libraries/funind:coq:tacn.functional-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional induction}}}}}


\index{discriminate (tactic)@\spxentry{discriminate}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{discriminate~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic proves any goal from an assumption stating that two
structurally different \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s 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.

\sphinxAtStartPar
The argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/core/basic: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
\sphinxstepexplicit %
\begin{footnote}[1]\phantomsection\label{\thesphinxscope.1}%
\sphinxAtStartFootnote
Reminder: opaque constants will not be expanded by δ 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/core/basic: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/core/basic: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}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is first introduced in the local context using
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\end{sphinxadmonition}
\index{No primitive equality found (error)@\spxentry{No primitive equality found}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.No-primitive-equality-found}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~primitive~equality~found.}}}}
\end{fulllineitems}\end{savenotes}

\index{Not a discriminable equality (error)@\spxentry{Not a discriminable equality}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.Not-a-discriminable-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~discriminable~equality.}}}}
\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{discriminate~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} followed by
\sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the identifier for the last
introduced hypothesis.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{discriminate~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{ediscriminate (tactic variant)@\spxentry{ediscriminate}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.ediscriminate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ediscriminate~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:id5}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ediscriminate~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This works the same as {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}} but if the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, or the
type of the hypothesis referred to by {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}, has uninstantiated
parameters, these parameters are left as existential variables.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{discriminate}}}}
\sphinxAtStartPar
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} <> {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, this behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{intro {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; discriminate {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\index{No discriminable equalities (error)@\spxentry{No discriminable equalities}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.No-discriminable-equalities}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~discriminable~equalities.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{injection (tactic)@\spxentry{injection}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof of a statement of conclusion \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}},
then {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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}

\sphinxAtStartPar
Consider the following goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{list} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{list}
\PYG{o}{|} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list}
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list}
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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 {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Scheme}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{Equality ...}}}
(see {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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:}
\sphinxAtStartPar
If some quantified hypothesis of the goal is named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}},
then \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\end{sphinxadmonition}
\index{Nothing to do, it is an equality between convertible terms (error)@\spxentry{Nothing to do, it is an equality between convertible terms}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives: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~terms.}}}}
\end{fulllineitems}\end{savenotes}

\index{Not a primitive equality (error)@\spxentry{Not a primitive equality}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.Not-a-primitive-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~primitive~equality.}}}}
\end{fulllineitems}\end{savenotes}

\index{Nothing to inject (error)@\spxentry{Nothing to inject}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.Nothing-to-inject}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nothing~to~inject.}}}}
\sphinxAtStartPar
This error is given when one side of the equality is not a constructor.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} followed by
\sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the identifier for the last
introduced hypothesis.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
This does the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{einjection (tactic variant)@\spxentry{einjection}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.einjection}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:id6}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This works the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{injection}}} but if the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, or the
type of the hypothesis referred to by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}, has uninstantiated
parameters, these parameters are left as existential variables.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection}}}}
\sphinxAtStartPar
If the current goal is of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} <> {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} , this behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{intro {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; injection {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\index{goal does not satisfy the expected preconditions (error)@\spxentry{goal does not satisfy the expected preconditions}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives: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{savenotes}


\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
These variants apply \sphinxcode{\sphinxupquote{\DUrole{notation}{intros \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}} after the call to
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives: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}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}} 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}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}}
to the number of new equalities. The original equality is erased if it
corresponds to a hypothesis.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}}}
\sphinxAtStartPar
These are equivalent to the previous variants but using instead the
syntax {\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection\_intropattern}}}}} which {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}}
uses. In particular \sphinxcode{\sphinxupquote{\DUrole{notation}{as {[}= \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}{]}}}} behaves
the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{as \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Structural Injection (flag)@\spxentry{Structural Injection}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Structural-Injection}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Structural~Injection}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} ensures that \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as}}}
(with an empty list of names). This flag is off by default.

\end{fulllineitems}\end{savenotes}

\index{Keep Proof Equalities (flag)@\spxentry{Keep Proof Equalities}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Keep-Proof-Equalities}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Keep~Proof~Equalities}}}}
\sphinxAtStartPar
By default, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} only creates new equalities between \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s
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 {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}
controls this behavior.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{inversion (tactic)@\spxentry{inversion}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Let the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic: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}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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{proofs/writing-proofs/reasoning-inductives:derive-inversion}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of inversion principles with Derive Inversion}}}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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 {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}s whose type is in sort
\sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}). This behavior can be turned off by using the
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Keep-Proof-Equalities}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Keep Proof Equalities}}}}} setting.
\end{sphinxadmonition}


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} then \sphinxcode{\sphinxupquote{\DUrole{notation}{inversion {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the identifier for the last introduced hypothesis.

\end{fulllineitems}\end{savenotes}

\index{inversion\_clear (tactic variant)@\spxentry{inversion\_clear}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_clear}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{inversion}}} and then erases \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} from the context.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}}
\sphinxAtStartPar
This generally behaves as inversion but using names in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}
for naming hypotheses. The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}} must have the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}p}}}$_{\text{11}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{1n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{| ... | p}}}$_{\text{m1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{mn}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{{]}}}}
with \sphinxcode{\sphinxupquote{m}} being the number of constructors of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. Be
careful that the list must be of length \sphinxcode{\sphinxupquote{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. \sphinxcode{\sphinxupquote{n = 0}}).The arguments of the i\sphinxhyphen{}th
constructor and the equalities that \sphinxcode{\sphinxupquote{inversion}} introduces in the
context of the goal corresponding to the i\sphinxhyphen{}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
\sphinxcode{\sphinxupquote{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{contains0} \PYG{o}{:} \PYG{n}{list} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{|} \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}{|} \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{n}{contains0\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{l}\PYG{o}{:}\PYG{n}{list} \PYG{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{list} \PYG{n}{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}{|} \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}{goal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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{n}{list} \PYG{n}{nat}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}}
\sphinxAtStartPar
This allows naming the hypotheses introduced by \sphinxcode{\sphinxupquote{\DUrole{notation}{inversion {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} in the
context.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}}
\sphinxAtStartPar
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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Let \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}, and then performing \sphinxcode{\sphinxupquote{inversion}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{inversion {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Let \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}, and then performing \sphinxcode{\sphinxupquote{inversion\_clear}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{inversion\_clear {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.

\end{fulllineitems}\end{savenotes}

\index{dependent inversion (tactic variant)@\spxentry{dependent inversion}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.dependent-inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
That must be used when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} for the corresponding
\sphinxcode{\sphinxupquote{\DUrole{notation}{@{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} in the goal.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}}
\sphinxAtStartPar
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{dependent inversion {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Like \sphinxcode{\sphinxupquote{dependent inversion}}, except that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is cleared from the
local context.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}}
\sphinxAtStartPar
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{dependent inversion\_clear {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{dependent inversion … with … (tactic variant)@\spxentry{dependent inversion … with …}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.dependent-inversion-_u2026-with-_u2026}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
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/core/basic: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 \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{),} \DUrole{name}{s}}},
then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} must be of type \sphinxcode{\sphinxupquote{\DUrole{name}{I}\DUrole{operator}{:}\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{),} \DUrole{name}{I} \DUrole{name}{x} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{s'}}} where
\sphinxcode{\sphinxupquote{\DUrole{name}{s'}}} is the type of the goal.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{dependent inversion {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} with {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
Like {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.dependent-inversion-_u2026-with-_u2026}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dependent inversion … with …}}}}} with but clears \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} from the
local context.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{dependent inversion\_clear {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} with {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{simple inversion (tactic variant)@\spxentry{simple inversion}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.simple-inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-or_and_intropattern_loc}]{\sphinxcrossref{\DUrole{hole}{or\_and\_intropattern\_loc}}}}}}}}
\sphinxAtStartPar
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{simple inversion}}.

\end{fulllineitems}\end{savenotes}

\index{inversion ... using ... (tactic)@\spxentry{inversion ... using ...}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion-...-using-...}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}~
\sphinxAtStartPar
Let \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic: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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~using~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This tactic behaves as generalizing \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}, then doing
\sphinxcode{\sphinxupquote{\DUrole{notation}{inversion {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} using {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{inversion\_sigma (tactic variant)@\spxentry{inversion\_sigma}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_sigma}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_sigma~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
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{proofs/writing-proofs/equality: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, you can pass it as
an argument to {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_sigma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion\_sigma}}}}}. This tactic also works for
\sphinxcode{\sphinxupquote{\DUrole{name}{sig}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{sigT2}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{sig2}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{ex}}}, and \sphinxcode{\sphinxupquote{\DUrole{name}{ex2}}} and there are similar \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_sig}}}
\sphinxcode{\sphinxupquote{\DUrole{operator}{***\_}\DUrole{name}{rect}}} induction lemmas.
\index{Type of ‘ident’ is not an equality of recognized Σ types: expected one of sig sig2 sigT sigT2 sigT2 ex or ex2 but got ‘term’ (error)@\spxentry{Type of ‘ident’ is not an equality of recognized Σ types: expected one of sig sig2 sigT sigT2 sigT2 ex or ex2 but got ‘term’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn.Type-of-_u2018ident_u2019-is-not-an-equality-of-recognized-_u03a3-types:-expected-one-of-sig-sig2-sigT-sigT2-sigT2-ex-or-ex2-but-got-_u2018term_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Type~of~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~not~an~equality~of~recognized~Σ~types:~expected~one~of~sig~sig2~sigT~sigT2~sigT2~ex~or~ex2~but~got~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
When applied to a hypothesis, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_sigma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion\_sigma}}}}} can only handle equalities of the
listed sigma types.

\end{fulllineitems}\end{savenotes}

\index{‘ident’ is not an equality of Σ types (error)@\spxentry{‘ident’ is not an equality of Σ types}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:exn._u2018ident_u2019-is-not-an-equality-of-_u03a3-types}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~not~an~equality~of~Σ~types}}}}
\sphinxAtStartPar
When applied to a hypothesis, {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_sigma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion\_sigma}}}}} can only be called on hypotheses that
are equalities using \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Logic}\DUrole{operator}{.}\DUrole{name}{Init}\DUrole{operator}{.}\DUrole{name}{eq}}}.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
\sphinxstyleemphasis{Non\sphinxhyphen{}dependent inversion}.

\sphinxAtStartPar
Let us consider the relation \sphinxcode{\sphinxupquote{\DUrole{name}{Le}}} over natural numbers:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Le} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{LeO} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{l+m+mi}{0} \PYG{n}{n}
\PYG{o}{|} \PYG{n}{LeS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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}

\sphinxAtStartPar
Let us consider the following goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
To prove the goal, we may need to reason by cases on \sphinxcode{\sphinxupquote{\DUrole{name}{H}}} and to derive
that \sphinxcode{\sphinxupquote{\DUrole{name}{m}}} is necessarily of the form \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{m0}\DUrole{operator}{)}}} for certain \sphinxcode{\sphinxupquote{\DUrole{name}{m0}}} and that
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{Le} \DUrole{name}{n} \DUrole{name}{m0}\DUrole{operator}{)}}}. Deriving these conditions corresponds to proving that the only
possible constructor of \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{Le} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{n}\DUrole{operator}{)} \DUrole{name}{m}\DUrole{operator}{)}}} is \sphinxcode{\sphinxupquote{\DUrole{name}{LeS}}} and that we can invert
the arrow in the type of \sphinxcode{\sphinxupquote{\DUrole{name}{LeS}}}. This inversion is possible because \sphinxcode{\sphinxupquote{\DUrole{name}{Le}}}
is the smallest set closed by the constructors \sphinxcode{\sphinxupquote{\DUrole{name}{LeO}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{LeS}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{inversion\PYGZus{}clear} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{m0} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Note that \sphinxcode{\sphinxupquote{\DUrole{name}{m}}} has been substituted in the goal for \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{m0}\DUrole{operator}{)}}} and that the
hypothesis \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{Le} \DUrole{name}{n} \DUrole{name}{m0}\DUrole{operator}{)}}} has been added to the context.

\sphinxAtStartPar
Sometimes it is interesting to have the equality \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{=} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{m0}\DUrole{operator}{)}}} in the
context to use it after. In that case we can use {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} that does
not clear the equalities:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{inversion} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{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}

\sphinxAtStartPar
\sphinxstyleemphasis{Dependent inversion.}

\sphinxAtStartPar
Let us consider the following goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
As \sphinxcode{\sphinxupquote{\DUrole{name}{H}}} occurs in the goal, we may want to reason by cases on its
structure and so, we would like inversion tactics to substitute \sphinxcode{\sphinxupquote{\DUrole{name}{H}}} by
the corresponding @term in constructor form. Neither {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} nor
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_clear}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion\_clear}}}}} do such a substitution. To have such a behavior we
use the dependent inversion tactics:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{dependent} \PYG{n}{inversion\PYGZus{}clear} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{m0} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Note that \sphinxcode{\sphinxupquote{\DUrole{name}{H}}} has been substituted by \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{LeS} \DUrole{name}{n} \DUrole{name}{m0} \DUrole{name}{l}\DUrole{operator}{)}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{m}}} by \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{m0}\DUrole{operator}{)}}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
\sphinxstyleemphasis{Using inversion\_sigma.}

\sphinxAtStartPar
Let us consider the following inductive type of
length\sphinxhyphen{}indexed lists, and a lemma about inverting equality of cons:

\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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{O}
\PYG{o}{|} \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{n}{vec\PYGZus{}sind} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
After performing inversion, we are left with an equality of existTs:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{inversion} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{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{n}{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}

\sphinxAtStartPar
We can turn this equality into a usable form with inversion\_sigma:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{inversion\PYGZus{}sigma}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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\PYGZus{}} \PYG{o}{:} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n}
      \PYG{n}{H2\PYGZus{}0} \PYG{o}{:} \PYG{n}{eq\PYGZus{}rect} \PYG{n}{n} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}\PYG{o}{)} \PYG{n}{xs} \PYG{n}{n} \PYG{n}{H2\PYGZus{}} \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}

\sphinxAtStartPar
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:

\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}{|}\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}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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\PYGZus{}0} \PYG{o}{:} \PYG{n}{eq\PYGZus{}rect} \PYG{n}{n} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}\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}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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\PYGZus{}0} \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}

\sphinxAtStartPar
Finally, we can finish the proof:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{assumption}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{using/libraries/funind:coq:tacn.functional-inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional inversion}}}}}


\index{fix (tactic)@\spxentry{fix}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.fix}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fix~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This tactic is a primitive tactic to start a proof by induction. In
general, it is easier to rely on higher\sphinxhyphen{}level induction tactics such
as the ones described in {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}.

\sphinxAtStartPar
In the syntax of the tactic, the identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} 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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} products.

\sphinxAtStartPar
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 global 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{proofs/writing-proofs/proof-mode:requestinginformation}]{\sphinxcrossref{\DUrole{std,std-ref}{Requesting information}}}}).

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fix~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}}~{[}\DUrole{curlies}{\{struct~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\}}{]}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} are the names of the induction hypotheses. The identifiers
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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}\end{savenotes}

\index{cofix (tactic)@\spxentry{cofix}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.cofix}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cofix~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This tactic starts a proof by coinduction. The identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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\sphinxhyphen{}inductive hypotheses is correct is
done only at the time of registering the lemma in the global 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{proofs/writing-proofs/proof-mode:requestinginformation}]{\sphinxcrossref{\DUrole{std,std-ref}{Requesting information}}}}).

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cofix~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} are the names of the coinduction hypotheses.

\end{fulllineitems}\end{savenotes}



\subsubsection{Equality and inductive sets}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:equality-and-inductive-sets}}
\sphinxAtStartPar
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}{\sphinxhyphen{}>}\DUrole{name}{A}\DUrole{operator}{\sphinxhyphen{}>}\DUrole{keyword,type}{Prop}}}, simply written with the infix
symbol \sphinxcode{\sphinxupquote{\DUrole{operator}{=}}}.
\index{decide equality (tactic)@\spxentry{decide equality}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.decide-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{decide~equality}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{compare (tactic)@\spxentry{compare}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.compare}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{compare~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic compares two given objects \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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\sphinxhyphen{}
goals \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} ={\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \sphinxhyphen{}> G}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{\textasciitilde{} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \sphinxhyphen{}> G}}}. The type of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} must satisfy the same restrictions as in the
tactic \sphinxcode{\sphinxupquote{decide equality}}.

\end{fulllineitems}\end{savenotes}

\index{simplify\_eq (tactic)@\spxentry{simplify\_eq}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.simplify_eq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simplify\_eq~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
Let \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} be the proof of a statement of conclusion \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} are structurally different (in the sense
described for the tactic {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}}), then the tactic
\sphinxcode{\sphinxupquote{simplify\_eq}} behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, otherwise it behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
If some quantified hypothesis of the goal is named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}},
then \sphinxcode{\sphinxupquote{\DUrole{notation}{simplify\_eq {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\end{sphinxadmonition}


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simplify\_eq~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} then
\sphinxcode{\sphinxupquote{\DUrole{notation}{simplify\_eq {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the identifier for the last
introduced hypothesis.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simplify\_eq~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}
\sphinxAtStartPar
This does the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{simplify\_eq {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{esimplify\_eq (tactic variant)@\spxentry{esimplify\_eq}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.esimplify_eq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{esimplify\_eq~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:id7}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{esimplify\_eq~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This works the same as {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.simplify_eq}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simplify\_eq}}}}} but if the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, or the
type of the hypothesis referred to by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}, has uninstantiated
parameters, these parameters are left as existential variables.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simplify\_eq}}}}
\sphinxAtStartPar
If the current goal has form \sphinxcode{\sphinxupquote{\DUrole{name}{t1} \DUrole{operator}{<>} \DUrole{name}{t2}}}, it behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{intro {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; simplify\_eq {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{dependent rewrite \sphinxhyphen{}> (tactic)@\spxentry{dependent rewrite \sphinxhyphen{}>}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.dependent-rewrite-->}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~rewrite~\sphinxhyphen{}>~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This tactic applies to any goal. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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/core/basic: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{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} tactics.

\end{fulllineitems}\end{savenotes}

\index{dependent rewrite <\sphinxhyphen{} (tactic variant)@\spxentry{dependent rewrite <\sphinxhyphen{}}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.dependent-rewrite-<-}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~rewrite~<\sphinxhyphen{}~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Analogous to {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.dependent-rewrite-->}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dependent rewrite \sphinxhyphen{}>}}}}} but uses the equality from right to
left.

\end{fulllineitems}\end{savenotes}



\subsubsection{Generation of induction principles with \sphinxstyleliteralintitle{\sphinxupquote{Scheme}}}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:generation-of-induction-principles-with-scheme}}\label{\detokenize{proofs/writing-proofs/reasoning-inductives:proofschemes-induction-principles}}\index{Scheme (command)@\spxentry{Scheme}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Scheme}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Scheme~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-scheme_kind}]{\sphinxcrossref{\DUrole{hole}{scheme\_kind}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-scheme_kind}]{\sphinxcrossref{\DUrole{hole}{scheme\_kind}}}}}\DUrole{notation-sup}{*}}}}}}~\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-scheme_kind}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-scheme_kind}]{\sphinxcrossref{\DUrole{hole}{scheme\_kind}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Equality for {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{Induction}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Minimality}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Elimination}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Case}} for {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}} Sort {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\DUrole{hole}{sort\_family}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\DUrole{hole}{sort\_family}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Set}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Prop}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{SProp}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Type}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}

\sphinxAtStartPar
A high\sphinxhyphen{}level tool for automatically generating
(possibly mutual) induction principles for given types and sorts.
Each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} is a different inductive type identifier belonging to
the same package of mutual inductive definitions.
The command generates the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}s as mutually recursive
definitions. Each term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} proves a general principle of mutual
induction for objects in type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
The name of the scheme. If not provided, the scheme name will be determined automatically
from the sorts involved.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{Minimality for {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}} Sort {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\DUrole{hole}{sort\_family}}}}}}}}] \leavevmode
\sphinxAtStartPar
Defines a non\sphinxhyphen{}dependent elimination principle more natural for inductively defined relations.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{Equality for {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}] \leavevmode
\sphinxAtStartPar
Tries to generate a Boolean equality and a proof of the decidability of the usual equality.
If {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}} involves other inductive types, their equality has to be defined first.

\end{description}

\end{fulllineitems}\end{savenotes}


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

\sphinxAtStartPar
Induction scheme for tree and forest.

\sphinxAtStartPar
A mutual induction principle for tree and forest in sort \sphinxcode{\sphinxupquote{Set}} can be defined using the command
\begin{quote}

\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}{|} \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}{tree\PYGZus{}sind} \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}{forest\PYGZus{}sind} \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}

\sphinxAtStartPar
You may now look at the type of tree\_forest\_rec:

\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
The principle \sphinxcode{\sphinxupquote{forest\_tree\_rec}} shares exactly the same premises, only
the conclusion now refers to the property of forests.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Predicates odd and even on naturals.

\sphinxAtStartPar
Let odd and even be inductively defined as:
\begin{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{odd} \PYG{o}{:} \PYG{n}{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{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{o}{|} \PYG{n}{evenO} \PYG{o}{:} \PYG{n}{even} \PYG{l+m+mi}{0}
  \PYG{o}{|} \PYG{n}{evenS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{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}{odd\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{even\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{even\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{quote}

\sphinxAtStartPar
The following command generates a powerful elimination principle:
\begin{quote}

\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}

\sphinxAtStartPar
The type of odd\_even for instance will be:

\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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{odd} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n}
\end{sphinxVerbatim}

\sphinxAtStartPar
The type of \sphinxcode{\sphinxupquote{even\_odd}} shares the same premises but the conclusion is
\sphinxcode{\sphinxupquote{(n:nat)(even n)\sphinxhyphen{}>(P0 n)}}.
\end{sphinxadmonition}


\paragraph{Automatic declaration of schemes}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:automatic-declaration-of-schemes}}\index{Elimination Schemes (flag)@\spxentry{Elimination Schemes}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Elimination-Schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Elimination~Schemes}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} enables automatic declaration of induction principles when defining a new
inductive type.  Defaults to on.

\end{fulllineitems}\end{savenotes}

\index{Nonrecursive Elimination Schemes (flag)@\spxentry{Nonrecursive Elimination Schemes}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Nonrecursive-Elimination-Schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nonrecursive~Elimination~Schemes}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} enables automatic declaration of induction
principles for types declared with the {\hyperref[\detokenize{language/core/variants:coq:cmd.Variant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variant}}}}} and
{\hyperref[\detokenize{language/core/records:coq:cmd.Record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} commands.  Defaults to off.

\end{fulllineitems}\end{savenotes}

\index{Case Analysis Schemes (flag)@\spxentry{Case Analysis Schemes}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Case-Analysis-Schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Case~Analysis~Schemes}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{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}\end{savenotes}

\index{Boolean Equality Schemes (flag)@\spxentry{Boolean Equality Schemes}\spxextra{flag}}\index{Decidable Equality Schemes (flag)@\spxentry{Decidable Equality Schemes}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Boolean-Equality-Schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Boolean~Equality~Schemes}}}}\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Decidable-Equality-Schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Decidable~Equality~Schemes}}}}
\sphinxAtStartPar
These {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flags}}}} control the automatic declaration of those Boolean equalities (see
the second variant of \sphinxcode{\sphinxupquote{Scheme}}).

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
You have to be careful with these flags since Coq may now reject well\sphinxhyphen{}defined
inductive types because it cannot compute a Boolean equality for them.
\end{sphinxadmonition}
\index{Rewriting Schemes (flag)@\spxentry{Rewriting Schemes}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:flag.Rewriting-Schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Rewriting~Schemes}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} governs generation of equality\sphinxhyphen{}related schemes such as congruence.

\end{fulllineitems}\end{savenotes}



\paragraph{Combined Scheme}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:combined-scheme}}\index{Combined Scheme (command)@\spxentry{Combined Scheme}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Combined-Scheme}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Combined~Scheme~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{def}}$}}}}~from~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\sphinxAtStartPar
This command is a tool for combining induction principles generated
by the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Scheme}}}}} command.
Each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a different inductive principle that must  belong
to the same package of mutual inductive principle definitions.
This command generates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{def}}$}}}}}}} as the conjunction of the
principles: it is built from the common premises of the principles
and concluded by the conjunction of their conclusions.
In the case where all the inductive principles used are in sort
\sphinxcode{\sphinxupquote{Prop}}, the propositional conjunction \sphinxcode{\sphinxupquote{and}} is used, otherwise
the simple product \sphinxcode{\sphinxupquote{prod}} is used instead.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
We can define the induction principles for trees and forests using:

\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}

\sphinxAtStartPar
Then we can build the combined induction principle which gives the
conjunction of the conclusions of each individual principle:

\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}

\sphinxAtStartPar
The type of tree\_forest\_mutind will be:

\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}

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

\sphinxAtStartPar
We can also combine schemes at sort \sphinxcode{\sphinxupquote{Type}}:
\end{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Scheme} \PYG{n}{tree\PYGZus{}forest\PYGZus{}rect} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{tree} \PYG{n}{Sort} \PYG{k+kt}{Type}
\PYG{k}{with} \PYG{n}{forest\PYGZus{}tree\PYGZus{}rect} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{forest} \PYG{n}{Sort} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{n}{forest\PYGZus{}tree\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}rect}\PYG{o}{,} \PYG{n}{forest\PYGZus{}tree\PYGZus{}rect} \PYG{n}{are} \PYG{n}{recursively} \PYG{n}{defined}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Combined} \PYG{n}{Scheme} \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutrect} \PYG{n}{from} \PYG{n}{tree\PYGZus{}forest\PYGZus{}rect}\PYG{o}{,} \PYG{n}{forest\PYGZus{}tree\PYGZus{}rect}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutrect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutrect} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutrect}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutrect}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P0} \PYG{o}{:} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\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}{*} \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}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{using/libraries/funind:functional-scheme}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Functional Scheme}}}}




\subsubsection{Generation of inversion principles with \sphinxstyleliteralintitle{\sphinxupquote{Derive}} \sphinxstyleliteralintitle{\sphinxupquote{Inversion}}}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:generation-of-inversion-principles-with-derive-inversion}}\label{\detokenize{proofs/writing-proofs/reasoning-inductives:derive-inversion}}\index{Derive Inversion (command)@\spxentry{Derive Inversion}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Derive-Inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~Inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{Sort~{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\DUrole{hole}{sort\_family}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Generates an inversion lemma for the
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion-...-using-...}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion ... using ...}}}}} tactic.  {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the name
of the generated lemma.  {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}} should be in the form
{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{(forall \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}}, {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} where
{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is the name of an inductive
predicate and \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}}}}} binds the variables occurring in the term
{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. The lemma is generated for the sort
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort\_family}}}}} corresponding to {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}.
Applying the lemma is equivalent to inverting the instance with the
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} tactic.

\end{fulllineitems}\end{savenotes}

\index{Derive Inversion\_clear (command)@\spxentry{Derive Inversion\_clear}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Derive-Inversion_clear}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~Inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{Sort~{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\DUrole{hole}{sort\_family}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
When applied, it is equivalent to having inverted the instance with the
tactic inversion replaced by the tactic \sphinxcode{\sphinxupquote{inversion\_clear}}.

\end{fulllineitems}\end{savenotes}

\index{Derive Dependent Inversion (command)@\spxentry{Derive Dependent Inversion}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Derive-Dependent-Inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~Dependent~Inversion~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~Sort~{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\DUrole{hole}{sort\_family}}}}}}}}
\sphinxAtStartPar
When applied, it is equivalent to having inverted the instance with
the tactic \sphinxcode{\sphinxupquote{dependent inversion}}.

\end{fulllineitems}\end{savenotes}

\index{Derive Dependent Inversion\_clear (command)@\spxentry{Derive Dependent Inversion\_clear}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Derive-Dependent-Inversion_clear}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~Dependent~Inversion\_clear~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~Sort~{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\DUrole{hole}{sort\_family}}}}}}}}
\sphinxAtStartPar
When applied, it is equivalent to having inverted the instance
with the tactic \sphinxcode{\sphinxupquote{dependent inversion\_clear}}.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Consider the relation \sphinxcode{\sphinxupquote{Le}} over natural numbers and the following
parameter \sphinxcode{\sphinxupquote{P}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Le} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{LeO} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{l+m+mi}{0} \PYG{n}{n}
\PYG{o}{|} \PYG{n}{LeS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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{n}{Le\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

\sphinxAtStartPar
To generate the inversion lemma for the instance \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{Le} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{n}\DUrole{operator}{)} \DUrole{name}{m}\DUrole{operator}{)}}} and the
sort \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}, we do:

\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{n}{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{n}{leminv} \PYG{k}{is} \PYG{n}{defined}

\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{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{m0} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Then we can use the proven inversion lemma:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{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}


\subsubsection{Examples of dependent destruction / dependent induction}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:examples-of-dependent-destruction-dependent-induction}}\label{\detokenize{proofs/writing-proofs/reasoning-inductives:dependent-induction}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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:

\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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
     \PYG{o}{|} \PYG{n}{LeO} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{l+m+mi}{0} \PYG{n}{n}
     \PYG{o}{|} \PYG{n}{LeS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{generalize\PYGZus{}eqs} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{gen\PYGZus{}x} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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:

\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}{goals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{n0} \PYG{o}{:} \PYG{n}{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}{goal} \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}

\sphinxAtStartPar
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.:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{gen\PYGZus{}x} \PYG{o}{:} \PYG{n}{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{n}{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}{p} \PYG{o}{\PYGZti{}}\PYG{o}{=} \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}

\sphinxAtStartPar
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:

\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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{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}

\sphinxAtStartPar
The higher\sphinxhyphen{}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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{ex} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{n}{n} \PYG{n}{m} \PYG{n}{H}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{dependent} \PYG{n}{destruction} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Implicit} \PYG{k+kn}{Arguments}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{vector} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{|} \PYG{n}{vnil} \PYG{o}{:} \PYG{n}{vector} \PYG{l+m+mi}{0}
         \PYG{o}{|} \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}

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{n}{n} \PYG{n}{v}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{dependent} \PYG{n}{destruction} \PYG{n}{v}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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 <> 0}}.


\paragraph{A larger example}
\label{\detokenize{proofs/writing-proofs/reasoning-inductives:a-larger-example}}
\sphinxAtStartPar
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\sphinxhyphen{}typed lambda\sphinxhyphen{}calculus formalized in a
dependently\sphinxhyphen{}typed style:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{type} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{|} \PYG{n}{base} \PYG{o}{:} \PYG{n}{type}
         \PYG{o}{|} \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}

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{ctx} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{|} \PYG{n}{empty} \PYG{o}{:} \PYG{n}{ctx}
         \PYG{o}{|} \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}

\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}

\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}{|} \PYG{n}{empty} \PYG{o}{=\PYGZgt{}} \PYG{n}{G}
         \PYG{o}{|} \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}

\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}

\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}{|} \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}{|} \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}{|} \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}{|} \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}

\sphinxAtStartPar
We have defined types and contexts which are snoc\sphinxhyphen{}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\sphinxhyphen{}typed terms, hence the
name. A term is either an application of:
\begin{itemize}
\item {} 
\sphinxAtStartPar
the axiom rule to type a reference to the first variable in a
context

\item {} 
\sphinxAtStartPar
the weakening rule to type an object in a larger context

\item {} 
\sphinxAtStartPar
the abstraction or lambda rule to type a function

\item {} 
\sphinxAtStartPar
the application to type an application of a function to an argument

\end{itemize}

\sphinxAtStartPar
Once we have this datatype we want to do proofs on it, like weakening:

\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}

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
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\sphinxhyphen{}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:

\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}

\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}

\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}

\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}

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{4} \PYG{n}{goals}
      
      \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}{goal} \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}{goal} \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}{goal} \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}

\sphinxAtStartPar
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.

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{destruct} \PYG{n}{D}\PYG{o}{..}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{4} \PYG{n}{goals}
      
      \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}{goal} \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}{goal} \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}{goal} \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}

\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}{goals}
      
      \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}{goal} \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}{goal} \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}{goal} \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}

\sphinxAtStartPar
Once the induction hypothesis has been narrowed to the right equality,
it can be used directly.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{n}{weak}\PYG{o}{,} \PYG{n}{IHterm}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{goals}
      
      \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}{goal} \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}{goal} \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}

\sphinxAtStartPar
Now concluding this subgoal is easy.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{constructor}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{IHterm}\PYG{o}{;} \PYG{k+kp}{reflexivity}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{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
\sphinxAtStartPar
Georges Gonthier, Assia Mahboubi, Enrico Tassi

\end{description}\end{quote}


\subsubsection{Introduction}
\label{\detokenize{proof-engine/ssreflect-proof-language:introduction}}
\sphinxAtStartPar
This chapter describes a set of tactics known as \DUrole{smallcaps}{SSReflect} originally
designed to provide support for the so\sphinxhyphen{}called \sphinxstyleemphasis{small scale reflection}
proof methodology. Despite the original purpose this set of tactic is
of general interest and is available in Coq starting from version 8.7.

\sphinxAtStartPar
\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 Coq.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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{=>}} 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.

\sphinxAtStartPar
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{=>}} that this task is
devoted. Tactics frequently leave new assumptions in the conclusion, and are
often followed by \sphinxcode{\sphinxupquote{=>}} 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:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Bookkeeping}}}}



\sphinxAtStartPar
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:tacn.generally-have}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{generally have}}}}} or {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.without-loss}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{without loss}}}}}.

\sphinxAtStartPar
\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.

\sphinxAtStartPar
\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.

\sphinxAtStartPar
Finally, \DUrole{smallcaps}{SSReflect} supports so\sphinxhyphen{}called reflection steps, typically
allowing to switch back and forth between the computational view and
logical view of a concept.

\sphinxAtStartPar
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}}}}.


\paragraph{Acknowledgments}
\label{\detokenize{proof-engine/ssreflect-proof-language:acknowledgments}}
\sphinxAtStartPar
The authors would like to thank Frédéric Blanqui, François Pottier and
Laurence Rideau for their comments and suggestions.


\subsubsection{Usage}
\label{\detokenize{proof-engine/ssreflect-proof-language:usage}}

\paragraph{Getting started}
\label{\detokenize{proof-engine/ssreflect-proof-language:getting-started}}
\sphinxAtStartPar
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:

\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:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{language/extensions/implicit-arguments:coq:flag.Implicit-Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Implicit Arguments}}}}}, {\hyperref[\detokenize{language/extensions/implicit-arguments:coq:flag.Strict-Implicit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Strict Implicit}}}}},
{\hyperref[\detokenize{language/extensions/implicit-arguments:coq:flag.Printing-Implicit-Defensive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Implicit Defensive}}}}}




\paragraph{Compatibility issues}
\label{\detokenize{proof-engine/ssreflect-proof-language:compatibility-issues}}\label{\detokenize{proof-engine/ssreflect-proof-language:compatibility-issues-ssr}}
\sphinxAtStartPar
Requiring the above modules creates an environment which is mostly
compatible with the rest of Coq, up to a few discrepancies:
\begin{itemize}
\item {} 
\sphinxAtStartPar
New keywords (\sphinxcode{\sphinxupquote{is}}) might clash with variable, constant, tactic or
tactical names, or with quasi\sphinxhyphen{}keywords in tactic or
notation commands.

\item {} 
\sphinxAtStartPar
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:tacn.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:tacn.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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
The extensions to the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} tactic are partly incompatible with those
available in current versions of Coq; in particular: \sphinxcode{\sphinxupquote{rewrite .. in
(type of k)}} or \sphinxcode{\sphinxupquote{rewrite .. in *}} or any other variant of {\hyperref[\detokenize{proofs/writing-proofs/equality: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 <\sphinxhyphen{} …}} or \sphinxcode{\sphinxupquote{rewrite \sphinxhyphen{}> …}}) to access the Coq rewrite tactic.

\item {} 
\sphinxAtStartPar
New symbols (\sphinxcode{\sphinxupquote{//}}, \sphinxcode{\sphinxupquote{/=}}, \sphinxcode{\sphinxupquote{//=}}) might clash with adjacent
existing symbols.
This can be avoided by inserting white spaces.

\item {} 
\sphinxAtStartPar
New constant and theorem names might clash with the user theory.
This can be avoided by not importing all of \DUrole{smallcaps}{SSReflect}:

\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}

\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
The generalization of if statements to non\sphinxhyphen{}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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} is {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} then {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/core/basic: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 {} 
\sphinxAtStartPar
The following flags can be unset to make \DUrole{smallcaps}{SSReflect} more compatible with
parts of Coq:

\end{itemize}
\index{SsrRewrite (flag)@\spxentry{SsrRewrite}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:flag.SsrRewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SsrRewrite}}}}
\sphinxAtStartPar
Controls whether the incompatible rewrite syntax is enabled (the default).
Disabling the {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} makes the syntax compatible with other parts of Coq.

\end{fulllineitems}\end{savenotes}

\index{SsrIdents (flag)@\spxentry{SsrIdents}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:flag.SsrIdents}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SsrIdents}}}}
\sphinxAtStartPar
Controls whether tactics can refer to \DUrole{smallcaps}{SSReflect}\sphinxhyphen{}generated variables that are
in the form \_xxx\_.  Scripts with explicit references to such variables
are fragile; they are prone to failure if the proof is later modified or
if the details of variable name generation change in future releases of Coq.

\sphinxAtStartPar
The default is on, which gives an error message when the user tries to
create such identifiers.  Disabling the {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} generates a warning instead,
increasing compatibility with other parts of Coq.

\end{fulllineitems}\end{savenotes}



\subsubsection{Gallina extensions}
\label{\detokenize{proof-engine/ssreflect-proof-language:gallina-extensions}}
\sphinxAtStartPar
Small\sphinxhyphen{}scale reflection makes an extensive use of the programming
subset of Gallina, Coq’s logical specification language. This subset
is quite suited to the description of functions on representations,
because it closely follows the well\sphinxhyphen{}established design of the ML
programming language. The \DUrole{smallcaps}{SSReflect} extension provides three additions
to Gallina, for pattern assignment, pattern testing, and polymorphism;
these mitigate minor but annoying discrepancies between Gallina and
ML.


\paragraph{Pattern assignment}
\label{\detokenize{proof-engine/ssreflect-proof-language:pattern-assignment}}
\sphinxAtStartPar
The \DUrole{smallcaps}{SSReflect} extension provides the following construct for
irrefutable pattern matching, that is, destructuring assignment:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let: {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Note the colon \sphinxcode{\sphinxupquote{:}} after the \sphinxcode{\sphinxupquote{let}} keyword, which avoids any ambiguity
with a function definition or Coq’s basic destructuring let. The let:
construct differs from the latter in that
\begin{itemize}
\item {} 
\sphinxAtStartPar
The pattern can be nested (deep pattern matching), in particular,
this allows expression of the form:

\end{itemize}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{let}\PYG{o}{:} \PYG{n}{exist} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)} \PYG{n}{p\PYGZus{}xy} \PYG{o}{:=} \PYG{n}{Hp} \PYG{k}{in} \PYG{n+nb+bp}{…} \PYG{o}{.}
\end{sphinxVerbatim}
\begin{itemize}
\item {} 
\sphinxAtStartPar
The destructured constructor is explicitly given in the pattern, and
is used for type inference.

\begin{sphinxadmonition}{note}{Example}

\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{n}{nat} \PYG{o}{*} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \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}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\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}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{let:}} construct is just (more legible) notation for the primitive
Gallina expression \sphinxcode{\sphinxupquote{\DUrole{notation}{match {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} with {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} end}}}.

\sphinxAtStartPar
The \DUrole{smallcaps}{SSReflect} destructuring assignment supports all the dependent
match annotations; the full syntax is
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let: {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{as {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{in {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{return {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
where the second {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} and the second {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} are \sphinxstyleemphasis{types}.

\sphinxAtStartPar
When the \sphinxcode{\sphinxupquote{as}} and \sphinxcode{\sphinxupquote{return}} keywords are both present, then {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is bound
in both the second {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} and the second {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}; variables
in the optional type {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} are bound only in the second term, and
other variables in the first  {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} are bound only in the third
{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, however.


\paragraph{Pattern conditional}
\label{\detokenize{proof-engine/ssreflect-proof-language:pattern-conditional}}\label{\detokenize{proof-engine/ssreflect-proof-language:pattern-conditional-ssr}}
\sphinxAtStartPar
The following construct can be used for a refutable pattern matching,
that is, pattern testing:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{if {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} is {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} then {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Although this construct is not strictly ML (it does exist in variants
such as the pattern calculus or the ρ\sphinxhyphen{}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}

\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}{Definition} \PYG{n}{null} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{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{k+kn}{Variable} \PYG{n}{a} \PYG{o}{:} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{list} \PYG{n}{d}\PYG{o}{)} \PYG{o}{:} \PYG{n}{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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
The pattern conditional also provides a notation for destructuring
assignment with a refutable pattern, adapted to the pure functional
setting of Gallina, which lacks a \sphinxcode{\sphinxupquote{Match\_Failure}} exception.

\sphinxAtStartPar
Like \sphinxcode{\sphinxupquote{let:}} above, the \sphinxcode{\sphinxupquote{if…is}} construct is just (more legible) notation
for the primitive Gallina expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{match {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} with {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} | \_ => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} end}}}.

\sphinxAtStartPar
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).

\sphinxAtStartPar
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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} is inl \_ then {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{if {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} then {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}

\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}

\sphinxAtStartPar
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:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Close Scope boolean\_if\_scope.}}

\sphinxAtStartPar
Like \sphinxcode{\sphinxupquote{let:}} above, the \sphinxcode{\sphinxupquote{if\sphinxhyphen{}is\sphinxhyphen{}then\sphinxhyphen{}else}}
construct supports
the dependent match annotations:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{if {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} is {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} as {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} return {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} then {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
As in \sphinxcode{\sphinxupquote{let:}} the variable {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} (and those in the type pattern)
are bound in the second {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}; {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is also bound in the
third {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} (but not in the fourth {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}), while the
variables in the first {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} are bound only in the third
{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\sphinxAtStartPar
Another variant allows to treat the \sphinxcode{\sphinxupquote{else}} case first:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{if {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} isn\textquotesingle{}t {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} then {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Note that {\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} eventually binds variables in the third
{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and not in the second {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.


\paragraph{Parametric polymorphism}
\label{\detokenize{proof-engine/ssreflect-proof-language:parametric-polymorphism}}\label{\detokenize{proof-engine/ssreflect-proof-language:parametric-polymorphism-ssr}}
\sphinxAtStartPar
Unlike ML, polymorphism in core Gallina is explicit: the type
parameters of polymorphic functions must be declared explicitly, and
supplied at each point of use. However, Coq provides two features to
suppress redundant parameters:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Sections are used to provide (possibly implicit) parameters for a
set of definitions.

\item {} 
\sphinxAtStartPar
Implicit arguments declarations are used to tell Coq to use type
inference to deduce some parameters from the context at each point of
call.

\end{itemize}

\sphinxAtStartPar
The combination of these features provides a fairly good emulation of
ML\sphinxhyphen{}style polymorphism, but unfortunately this emulation breaks down
for higher\sphinxhyphen{}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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{all\PYGZus{}null} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Unfortunately, such higher\sphinxhyphen{}order expressions are quite frequent in
representation functions, especially those which use Coq's
\sphinxcode{\sphinxupquote{Structures}} to emulate Haskell typeclasses.

\sphinxAtStartPar
Therefore, \DUrole{smallcaps}{SSReflect} provides a variant of Coq’s implicit argument
declaration, which causes Coq to fill in some implicit parameters at
each point of use, e.g., the above definition can be written:

\begin{sphinxadmonition}{note}{Example}

\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{n}{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}

\sphinxAtStartPar
Better yet, it can be omitted entirely, since \sphinxcode{\sphinxupquote{\DUrole{name}{all\_null} \DUrole{name}{s}}} isn’t much of
an improvement over \sphinxcode{\sphinxupquote{\DUrole{name}{all} \DUrole{name}{null} \DUrole{name}{s}}}.

\sphinxAtStartPar
The syntax of the new declaration is
\index{Prenex Implicits (command)@\spxentry{Prenex Implicits}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This command checks that each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}} is the name of a functional
constant, whose implicit arguments are prenex, i.e., the first
\(n_i > 0\) arguments of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}} are implicit; then it assigns
\sphinxcode{\sphinxupquote{Maximal Implicit}} status to these arguments.

\sphinxAtStartPar
As these prenex implicit arguments are ubiquitous and have often large
display strings, it is strongly recommended to change the default
display settings of 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

\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}

\end{fulllineitems}\end{savenotes}



\paragraph{Anonymous arguments}
\label{\detokenize{proof-engine/ssreflect-proof-language:anonymous-arguments}}
\sphinxAtStartPar
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:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-binder}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{\& {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
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\sphinxhyphen{}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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{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{n}{cons} \PYG{k}{of} \PYG{n}{A} \PYG{o}{\PYGZam{}} \PYG{n}{list} \PYG{n}{A}\PYG{o}{.}
    \PYG{n}{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{n}{list\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Wildcards}
\label{\detokenize{proof-engine/ssreflect-proof-language:wildcards}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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 {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}}), 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}}}}).


\paragraph{Definitions}
\label{\detokenize{proof-engine/ssreflect-proof-language:definitions}}\label{\detokenize{proof-engine/ssreflect-proof-language:definitions-ssr}}\index{pose (ssreflect) (tactic)@\spxentry{pose (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.pose-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose}}}}
\sphinxAtStartPar
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}\end{savenotes}


\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{t} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
is a valid tactic expression.

\sphinxAtStartPar
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}}}}} supports parameters:

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
      
      \PYG{n}{f} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{k}{fix} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{x}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
defines a local fixpoint \sphinxcode{\sphinxupquote{f}}, which mimics the standard plus operation
on natural numbers.

\sphinxAtStartPar
Similarly, local cofixpoints can be defined by a tactic of the form:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{k}{cofix} \PYG{n}{f} \PYG{o}{(}\PYG{n}{arg} \PYG{o}{:} \PYG{n}{T}\PYG{o}{)} \PYG{o}{:=} \PYG{n+nb+bp}{…} \PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
is shorthand for:

\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}

\sphinxAtStartPar
When the local definition of a function involves both arguments and
holes, hole abstractions appear first. For instance, the tactic:

\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}

\sphinxAtStartPar
is shorthand for:

\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}

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
adds to the context the local definition:

\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}

\sphinxAtStartPar
The generalization of wildcards makes the use of the pose tactic
resemble ML\sphinxhyphen{}like definitions of polymorphic functions.


\paragraph{Abbreviations}
\label{\detokenize{proof-engine/ssreflect-proof-language:abbreviations}}\label{\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}}\index{set (ssreflect) (tactic)@\spxentry{set (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.set-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
The \DUrole{smallcaps}{SSReflect} \sphinxcode{\sphinxupquote{set}} tactic performs abbreviations: it introduces a
defined constant for a subterm appearing in the goal and/or in the
context.

\sphinxAtStartPar
\DUrole{smallcaps}{SSReflect} extends the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{set}}}}} tactic by supplying:
\begin{itemize}
\item {} 
\sphinxAtStartPar
an open syntax, similarly to the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.pose-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose}}}}} tactic;

\item {} 
\sphinxAtStartPar
a more aggressive matching algorithm;

\item {} 
\sphinxAtStartPar
an improved interpretation of wildcards, taking advantage of the
matching algorithm;

\item {} 
\sphinxAtStartPar
an improved occurrence selection mechanism allowing to abstract only
selected occurrences of a term.

\end{itemize}

\end{fulllineitems}\end{savenotes}

\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{curlies}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{+}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\sphinxhyphen{}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{*}} \}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
where:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a fresh identifier chosen by the user.

\item {} 
\sphinxAtStartPar
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/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} are mandatory.

\item {} 
\sphinxAtStartPar
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, it is rather used as a flag to signal the intent of the user to
clear the name following it (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:ssr-rewrite-occ-switch}]{\sphinxcrossref{\DUrole{std,std-ref}{Occurrence switches and redex switches}}}} and
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}})

\end{itemize}

\sphinxAtStartPar
The tactic:

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{f} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}

\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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{f} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
The type annotation may contain wildcards, which will be filled
with the appropriate value by the matching process.

\sphinxAtStartPar
The tactic first tries to find a subterm of the goal matching
the second {\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} and a definition \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic: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.


\subparagraph{Matching}
\label{\detokenize{proof-engine/ssreflect-proof-language:matching}}
\sphinxAtStartPar
The matching algorithm compares a pattern {\hyperref[\detokenize{language/core/basic: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 {} 
\sphinxAtStartPar
If the head of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is a constant, then it should be syntactically
equal to the head symbol of the subterm.

\item {} 
\sphinxAtStartPar
If this head is a projection of a canonical structure, then
canonical structure equations are used for the matching.

\item {} 
\sphinxAtStartPar
If the head of term is \sphinxstyleemphasis{not} a constant, the subterm should have the
same structure (λ abstraction, let…in structure …).

\item {} 
\sphinxAtStartPar
If the head of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is a hole, the subterm should have at least as
many arguments as {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\end{itemize}

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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 {} 
\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goal}
      
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{unkeyed} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z}\PYG{o}{)} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
Moreover:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Multiple holes in \sphinxcode{\sphinxupquote{term}} are treated as independent placeholders.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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 {} 
\sphinxAtStartPar
The type of the subterm matched should fit the type (possibly casted
by some type annotations) of the pattern \sphinxcode{\sphinxupquote{term}}.

\item {} 
\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{n}{Fail} \PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{l+m+mi}{1}\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{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 {} 
\sphinxAtStartPar
Typeclass inference should fill in any residual hole, but matching
should never assign a value to a global existential variable.

\end{itemize}


\subparagraph{Occurrence selection}
\label{\detokenize{proof-engine/ssreflect-proof-language:occurrence-selection}}\label{\detokenize{proof-engine/ssreflect-proof-language:occurrence-selection-ssr}}
\sphinxAtStartPar
\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, …

\sphinxAtStartPar
An \sphinxstyleemphasis{occurrence switch} can be:
\begin{itemize}
\item {} 
\sphinxAtStartPar
A list natural numbers \sphinxcode{\sphinxupquote{\{+ n1 … nm\}}}
of occurrences affected by the tactic.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Notice that some occurrences of a given term may be
hidden to the user, for example because of a notation. Setting the
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} flag causes these hidden occurrences to
be shown when the term is displayed.  This setting
should be used to find the correct coding of the occurrences to be
selected %
\begin{footnote}[33]\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}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
A list \sphinxcode{\sphinxupquote{\{\sphinxhyphen{} n1 … nm\}}} of occurrences \sphinxstyleemphasis{not} to be affected by the
tactic.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Note that, in this goal, it behaves like \sphinxcode{\sphinxupquote{set x := \{1 3\}(f 2).}}

\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
The switch \sphinxcode{\sphinxupquote{\{\sphinxhyphen{}\}}} imposes that \sphinxstyleemphasis{no} occurrences of the term should be
affected by the tactic. The tactic: \sphinxcode{\sphinxupquote{set x := \{\sphinxhyphen{}\}(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}

\sphinxAtStartPar
It is important to remember that matching \sphinxstyleemphasis{precedes} occurrence
selection.
\begin{quote}

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{a} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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{n}{Fail} \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}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Only} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2} \PYG{n}{occurrence} \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}


\paragraph{Basic localization}
\label{\detokenize{proof-engine/ssreflect-proof-language:basic-localization}}\label{\detokenize{proof-engine/ssreflect-proof-language:basic-localization-ssr}}
\sphinxAtStartPar
It is possible to define an abbreviation for a term appearing in the
context of a goal thanks to the \sphinxcode{\sphinxupquote{in}} tactical.


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}~\begin{quote}

\sphinxAtStartPar
This variant of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.set-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{set}}}}} introduces a defined constant
called {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} in the context, and folds it in
the context entries mentioned on the right hand side of \sphinxcode{\sphinxupquote{in}}.
The body of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the first subterm matching these context
entries (taken in the given order).
\end{quote}

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{t} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{t} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{z} \PYG{o}{:=} \PYG{l+m+mi}{3} \PYG{o}{:} \PYG{n}{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{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~*}}}}~\begin{quote}

\sphinxAtStartPar
This variant matches {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and then folds {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} similarly
in all the given context entries but also folds {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} in the goal.
\end{quote}

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{t} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{t} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{z} \PYG{o}{:=} \PYG{l+m+mi}{3} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Indeed, remember that 4 is just a notation for (S 3).
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
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}}}}.


\subsubsection{Basic tactics}
\label{\detokenize{proof-engine/ssreflect-proof-language:basic-tactics}}\label{\detokenize{proof-engine/ssreflect-proof-language:basic-tactics-ssr}}
\sphinxAtStartPar
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\sphinxhyphen{}flow
of a proof script. This is especially true for reflection\sphinxhyphen{}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 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\sphinxhyphen{}tacticals), shared across most \DUrole{smallcaps}{SSReflect} tactics, and thus form
the foundation of the \DUrole{smallcaps}{SSReflect} proof language.


\paragraph{Bookkeeping}
\label{\detokenize{proof-engine/ssreflect-proof-language:bookkeeping}}\label{\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}}
\sphinxAtStartPar
During the course of a proof Coq always present the user with a
\sphinxstyleemphasis{sequent} whose general form is:

\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}

\sphinxAtStartPar
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} \sphinxcode{\sphinxupquote{dj}} , 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 \sphinxhyphen{}>}},
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”.

\sphinxAtStartPar
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 α\sphinxhyphen{}conversion.

\sphinxAtStartPar
Similarly, basic deductive steps such as apply can only operate on the
goal because the 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}[34]\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.

\sphinxAtStartPar
In \DUrole{smallcaps}{SSReflect} these moves are performed by two \sphinxstyleemphasis{tacticals} \sphinxcode{\sphinxupquote{=>}} and
\sphinxcode{\sphinxupquote{:}}, so that the bookkeeping required by a deductive step can be
directly associated with 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.

\sphinxAtStartPar
Now \sphinxcode{\sphinxupquote{move}} does essentially nothing: it is mostly a placeholder for
\sphinxcode{\sphinxupquote{=>}} and \sphinxcode{\sphinxupquote{:}}. The \sphinxcode{\sphinxupquote{=>}} 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}

\sphinxAtStartPar
For example, the proof of %
\begin{footnote}[35]\sphinxAtStartFootnote
The name \sphinxcode{\sphinxupquote{subnK}} reads as “right cancellation rule for nat
subtraction”.
%
\end{footnote}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{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}

\sphinxAtStartPar
might start with

\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}{goal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
where move does nothing, but \sphinxcode{\sphinxupquote{=> 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 <=  m}}, thus exposing the
conclusion \sphinxcode{\sphinxupquote{m \sphinxhyphen{} n + n = m}}.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{:}} tactical is the converse of \sphinxcode{\sphinxupquote{=>}}, indeed it removes facts and
constants from the context by turning them into variables and
assumptions.

\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}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{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}

\sphinxAtStartPar
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 <= m \sphinxhyphen{}> m \sphinxhyphen{} n + n = m}}
which can be proved by induction on \sphinxcode{\sphinxupquote{n}} using \sphinxcode{\sphinxupquote{elim: n}}.
\end{sphinxadmonition}

\sphinxAtStartPar
Because they are tacticals, \sphinxcode{\sphinxupquote{:}} and \sphinxcode{\sphinxupquote{=>}} can be combined, as in

\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
Furthermore, \DUrole{smallcaps}{SSReflect} redefines the basic 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{=>}}. 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}

\sphinxAtStartPar
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{=>}} 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}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{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}{goal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{[|}\PYG{n}{n} \PYG{n}{IHn}\PYG{o}{]} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{o}{\PYGZus{}} \PYG{o}{|} \PYG{n}{lt\PYGZus{}n\PYGZus{}m}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goal} \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}

\sphinxAtStartPar
which breaks down the proof into two subgoals, the second one
having in its context
\sphinxcode{\sphinxupquote{lt\_n\_m : S n <= m}} and
\sphinxcode{\sphinxupquote{IHn : forall m, n <= m \sphinxhyphen{}> m \sphinxhyphen{} n + n = m}}.
\end{sphinxadmonition}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{:}} and \sphinxcode{\sphinxupquote{=>}} 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 {} 
\sphinxAtStartPar
\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 {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{tactic => 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}

\sphinxAtStartPar
These pushes and pops do not need to balance out as in the examples
above, so \sphinxcode{\sphinxupquote{move: m le\_n\_m => p}}
would rename \sphinxcode{\sphinxupquote{m}} into \sphinxcode{\sphinxupquote{p}}, but leave an extra assumption \sphinxcode{\sphinxupquote{n <= p}}
in the goal.

\sphinxAtStartPar
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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{=\PYGZgt{}} \PYG{o}{[|}\PYG{n}{m} \PYG{n}{IHm}\PYG{o}{]} \PYG{n}{n} \PYG{n}{le\PYGZus{}n}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The general form of the localization tactical in is also best
explained in terms of the goal stack:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
tactic in a H1 H2 *.
\end{sphinxVerbatim}

\sphinxAtStartPar
is basically equivalent to

\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}

\sphinxAtStartPar
with two differences: the in tactical will preserve the body of an if a
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}}.

\sphinxAtStartPar
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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{:} \PYG{n}{n} \PYG{o}{=\PYGZgt{}} \PYG{o}{[|}\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}

\sphinxAtStartPar
instead of

\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}{[|}\PYG{n}{n} \PYG{n}{IHn}\PYG{o}{]} \PYG{n}{m} \PYG{n}{le\PYGZus{}n\PYGZus{}m}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This is quite useful for inductive proofs that involve many facts.

\sphinxAtStartPar
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.


\paragraph{The defective tactics}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics}}\label{\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}}
\sphinxAtStartPar
In this section we briefly present the three basic tactics performing
context manipulations and the main backward chaining tool.


\subparagraph{The move tactic.}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-move-tactic}}\index{move (ssreflect) (tactic)@\spxentry{move (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.move-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move}}}}
\sphinxAtStartPar
This tactic, in its defective form, behaves like the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}} tactic.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ssreflect}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{not} \PYG{n}{False}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\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{n}{False}

\PYG{k}{move}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
More precisely, the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.move-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move}}}}} tactic inspects the goal and does nothing
({\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\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 {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}} otherwise.

\sphinxAtStartPar
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{proofs/writing-proofs/equality:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} tactics.

\end{fulllineitems}\end{savenotes}



\subparagraph{The case tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-case-tactic}}\label{\detokenize{proof-engine/ssreflect-proof-language:the-case-tactic-ssr}}\index{case (ssreflect) (tactic)@\spxentry{case (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.case-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{case}}}}
\sphinxAtStartPar
This 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}}}}).

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(x, y) = (1, 2) \PYGZhy{}\PYGZgt{} G.
\end{sphinxVerbatim}

\sphinxAtStartPar
into:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
x = 1 \PYGZhy{}\PYGZgt{} y = 2 \PYGZhy{}\PYGZgt{} G.
\end{sphinxVerbatim}

\sphinxAtStartPar
The {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}} can generate the following warning:
\index{SSReflect: cannot obtain new equations out of ... (warning)@\spxentry{SSReflect: cannot obtain new equations out of ...}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:warn.SSReflect:-cannot-obtain-new-equations-out-of-...}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SSReflect:~cannot~obtain~new~equations~out~of~...}}}}
\sphinxAtStartPar
The tactic was run on an equation that cannot generate simpler equations,
for example \sphinxcode{\sphinxupquote{x = 1}}.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
The warning can be silenced or made fatal by using the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Warnings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Warnings}}}}} option
and the \sphinxcode{\sphinxupquote{spurious\sphinxhyphen{}ssr\sphinxhyphen{}injection}} key.

\sphinxAtStartPar
Finally the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}} tactic of \DUrole{smallcaps}{SSReflect} performs \sphinxcode{\sphinxupquote{\DUrole{name}{False}}} elimination, even
if no branch is generated by this case operation. Hence the tactic
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}} on a goal of the form \sphinxcode{\sphinxupquote{\DUrole{name}{False} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{G}}} will succeed and
prove the goal.

\end{fulllineitems}\end{savenotes}



\subparagraph{The elim tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-elim-tactic}}\index{elim (ssreflect) (tactic)@\spxentry{elim (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.elim-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim}}}}
\sphinxAtStartPar
This tactic performs inductive elimination on inductive types. In its
defective form, the tactic performs inductive elimination on a goal whose
top assumption has an inductive type.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{m} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{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}{goals}
      
      \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}

\end{fulllineitems}\end{savenotes}



\subparagraph{The apply tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-apply-tactic}}\label{\detokenize{proof-engine/ssreflect-proof-language:apply-ssr}}\index{apply (ssreflect) (tactic)@\spxentry{apply (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.apply-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This is the main backward chaining tactic of the proof system.
It takes as argument any {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and applies it to the goal.
Assumptions in the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} that don’t directly match the goal
may generate one or more subgoals.

\sphinxAtStartPar
In its defective form, this tactic is a synonym for:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
intro top; first [refine top | refine (top \PYGZus{}) | refine (top \PYGZus{} \PYGZus{}) | …]; clear top.
\end{sphinxVerbatim}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{\DUrole{name}{top}}} is a fresh name, and the sequence of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactics
tries to catch the appropriate number of wildcards to be inserted. Note that
this use of the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic implies that the tactic tries to match
the goal up to expansion of constants and evaluation of subterms.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.apply-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} has a special behavior on goals containing
existential metavariables of sort \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}.

\begin{sphinxadmonition}{note}{Example}

\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}{|} \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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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{n}{nat} \PYG{o}{|} \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}{goals}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{2}\PYG{o}{)}
      
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goal} \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{n}{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}{goal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{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{n}{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}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that the last \sphinxcode{\sphinxupquote{\_}} of the tactic
\sphinxcode{\sphinxupquote{apply: (ex\_intro \_ (exist \_ y \_))}}
represents a proof that \sphinxcode{\sphinxupquote{y < 3}}. Instead of generating the goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
0 \PYGZlt{} proj1\PYGZus{}sig (exist (fun n : nat =\PYGZgt{} n \PYGZlt{} 3) y ?Goal).
\end{sphinxVerbatim}

\sphinxAtStartPar
the system tries to prove \sphinxcode{\sphinxupquote{y < 3}} calling the trivial tactic.
If it succeeds, let’s say because the context contains
\sphinxcode{\sphinxupquote{H : y < 3}}, then the
system generates the following goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
0 \PYGZlt{} proj1\PYGZus{}sig (exist (fun n =\PYGZgt{} n \PYGZlt{} 3) y H).
\end{sphinxVerbatim}

\sphinxAtStartPar
Otherwise the missing proof is considered to be irrelevant, and is
thus discharged generating the two goals shown above.

\sphinxAtStartPar
Last, the user can replace the trivial tactic by defining an Ltac
expression named \sphinxcode{\sphinxupquote{ssrautoprop}}.
\end{sphinxadmonition}


\paragraph{Discharge}
\label{\detokenize{proof-engine/ssreflect-proof-language:discharge}}\label{\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}}
\sphinxAtStartPar
The general syntax of the discharging tactical \sphinxcode{\sphinxupquote{:}} is:
\index{… : … (ssreflect) (tactic)@\spxentry{… : … (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn._u2026-:-_u2026-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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}\end{savenotes}

\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{curlies}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} \}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
with the following requirements:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\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 {} 
\sphinxAtStartPar
The optional {\hyperref[\detokenize{language/core/basic: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 {} 
\sphinxAtStartPar
An {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} selects occurrences of {\hyperref[\detokenize{language/core/basic: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 {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic}}}}} is \sphinxcode{\sphinxupquote{apply}} or \sphinxcode{\sphinxupquote{exact}}.

\item {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
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}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
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}[36]\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 {} 
\sphinxAtStartPar
These occurrences are replaced by a new variable; in particular, if
term is a fact, this adds an assumption to the goal.

\item {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
For example, the tactic:

\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 {} 
\sphinxAtStartPar
first generalizes \sphinxcode{\sphinxupquote{(refl\_equal n : n = n)}};

\item {} 
\sphinxAtStartPar
then generalizes the second occurrence of \sphinxcode{\sphinxupquote{n}}.

\item {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
Therefore this tactic changes any goal \sphinxcode{\sphinxupquote{G}} into

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{forall} \PYG{n}{n} \PYG{n}{n0} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{G}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
where the name \sphinxcode{\sphinxupquote{n0}} is picked by the Coq display function, and assuming
\sphinxcode{\sphinxupquote{n}} appeared only in \sphinxcode{\sphinxupquote{G}}.

\sphinxAtStartPar
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}}.

\sphinxAtStartPar
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.


\subparagraph{Clear rules}
\label{\detokenize{proof-engine/ssreflect-proof-language:clear-rules}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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/core/basic: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.

\sphinxAtStartPar
If tactic is \sphinxcode{\sphinxupquote{move}} or \sphinxcode{\sphinxupquote{case}} and an equation {\hyperref[\detokenize{language/core/basic: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}}}}).

\sphinxAtStartPar
Intro patterns (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}})
and the \sphinxcode{\sphinxupquote{rewrite}} tactic (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}})
let one place a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} in the middle of other items
(namely identifiers, views and rewrite rules).  This can trigger the
addition of proof context items to the ones being explicitly
cleared, and in turn this can result in clear errors (e.g. if the
context item automatically added occurs in the goal).  The
relevant sections describe ways to avoid the unintended clear of
context items.


\subparagraph{Matching for apply and exact}
\label{\detokenize{proof-engine/ssreflect-proof-language:matching-for-apply-and-exact}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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}}.

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{Hfg} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
    \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{n}{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{n}{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}

\sphinxAtStartPar
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.


\subparagraph{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) (tactic)@\spxentry{abstract (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.abstract-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{abstract:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
This tactic assigns an abstract constant previously introduced with the
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}: {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}}} intro pattern (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}).

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
In a goal like the following:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
m : nat
abs : \PYGZlt{}hidden\PYGZgt{}
n : nat
=============
m \PYGZlt{} 5 + n
\end{sphinxVerbatim}

\sphinxAtStartPar
The tactic \sphinxcode{\sphinxupquote{\DUrole{name}{abstract}\DUrole{operator}{:} \DUrole{name}{abs} \DUrole{name}{n}}} first generalizes the goal with respect to \sphinxcode{\sphinxupquote{\DUrole{name}{n}}}
(that is not visible to the abstract constant abs) and then assigns
abs. The resulting goal is:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
m : nat
n : nat
=============
m \PYGZlt{} 5 + n
\end{sphinxVerbatim}

\sphinxAtStartPar
Once this subgoal is closed, all other goals having abs in their
context see the type assigned to \sphinxcode{\sphinxupquote{abs}}. In this case:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
m : nat
abs : forall n, m \PYGZlt{} 5 + n
=============
…
\end{sphinxVerbatim}

\sphinxAtStartPar
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}}}}.


\paragraph{Introduction in the context}
\label{\detokenize{proof-engine/ssreflect-proof-language:introduction-in-the-context}}\label{\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
All these operations are performed by the introduction tactical \sphinxcode{\sphinxupquote{=>}},
whose general syntax is
\index{=> (tactic)@\spxentry{=>}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.=>}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}~=>~\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}\end{savenotes}

\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\DUrole{hole}{i\_view}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_block}]{\sphinxcrossref{\DUrole{hole}{i\_block}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{/=}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{//}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{//=}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\DUrole{hole}{i\_view}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\{\}}\DUrole{notation-sup}{?}} \DUrole{alternative}{\DUrole{alternative-block}{/{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{/ltac:( {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} )}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\_}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{?}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{*}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{+}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\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{alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{?}\DUrole{notation-sub}{|}} {]}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\sphinxhyphen{}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[}: \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} {]}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_block}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_block}]{\sphinxcrossref{\DUrole{hole}{i\_block}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{[}\textasciicircum{} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[}\textasciicircum{}\textasciitilde{} \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}} {]}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{=>}} tactical first executes {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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}}}}}
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}
(see {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}}:) each performs an introduction operation, i.e., pops some
variables or assumptions from the goal.


\subparagraph{Simplification items}
\label{\detokenize{proof-engine/ssreflect-proof-language:simplification-items}}
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
\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 {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{/=}} simplifies the goal by performing partial evaluation, as per the
tactic {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} %
\begin{footnote}[37]\sphinxAtStartFootnote
Except /= does not expand the local definitions created by the
\DUrole{smallcaps}{SSReflect} in tactical.
%
\end{footnote}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{//=}} combines both kinds of simplification; it is equivalent to
\sphinxcode{\sphinxupquote{/= //}}, i.e., \sphinxcode{\sphinxupquote{simpl; try done}}.

\end{itemize}

\sphinxAtStartPar
When an {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} immediately precedes 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.


\subparagraph{Views}
\label{\detokenize{proof-engine/ssreflect-proof-language:views}}
\sphinxAtStartPar
The first entry in the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_view}}}}} grammar rule, \sphinxcode{\sphinxupquote{\DUrole{notation}{/{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{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}}}}).
It interprets the top of the stack with the view {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.
It is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{move/{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\sphinxAtStartPar
A {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} that immediately precedes an {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_view}}}}}
is complemented with the name of the view if an only if the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_view}}}}}
is a simple proof context entry %
\begin{footnote}[42]\sphinxAtStartFootnote
A simple proof context entry is a naked identifier (i.e. not between
parentheses) designating a context entry that is not a section variable.
%
\end{footnote}.
E.g. \sphinxcode{\sphinxupquote{\{\}/v}} is equivalent to \sphinxcode{\sphinxupquote{/v\{v\}}}.
This behavior can be avoided by separating the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}}
from the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_view}}}}} with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} intro pattern or by putting
parentheses around the view.

\sphinxAtStartPar
A {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} that immediately precedes an {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_view}}}}}
is executed after the view application.

\sphinxAtStartPar
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.

\sphinxAtStartPar
The second entry in the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_view}}}}} grammar rule,
\sphinxcode{\sphinxupquote{/ltac:(}} {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic}}}}} \sphinxcode{\sphinxupquote{)}}, executes {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic}}}}}.
Notations can be used to name tactics,  for example

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}myop\PYGZsq{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{ltac}\PYG{o}{:}\PYG{o}{(}\PYG{n}{my} \PYG{n}{ltac} \PYG{n}{code}\PYG{o}{)}\PYG{o}{)} \PYG{o}{:} \PYG{n}{ssripat\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
lets one write just \sphinxcode{\sphinxupquote{/myop}} in the intro pattern. Note the scope
annotation: views are interpreted opening the \sphinxcode{\sphinxupquote{ssripat}} scope.  We
provide the following ltac views: \sphinxcode{\sphinxupquote{/{[}dup{]}}} to duplicate the top of
the stack, \sphinxcode{\sphinxupquote{/{[}swap{]}}} to swap the two first elements and \sphinxcode{\sphinxupquote{/{[}apply{]}}}
to apply the top of the stack to the next.


\subparagraph{Intro patterns}
\label{\detokenize{proof-engine/ssreflect-proof-language:intro-patterns}}
\sphinxAtStartPar
\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}] \leavevmode
\sphinxAtStartPar
pops the top variable, assumption, or local definition into
a new constant, fact, or defined constant {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, respectively.
Note that defined constants cannot be introduced when δ\sphinxhyphen{}expansion is
required to expose the top variable or assumption.
A {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} (even an empty one) immediately preceding an
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is complemented with that {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} if and only if
the identifier is a simple proof context entry \sphinxfootnotemark[42].
As a consequence  by prefixing the
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} with \sphinxcode{\sphinxupquote{\{\}}} one can \sphinxstyleemphasis{replace} a context entry.
This behavior can be avoided by separating the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}}
from the {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} intro pattern.

\item[{\sphinxcode{\sphinxupquote{>}}}] \leavevmode
\sphinxAtStartPar
pops every variable occurring in the rest of the stack.
Type class instances are popped even if they don't occur
in the rest of the stack.
The tactic \sphinxcode{\sphinxupquote{move=> >}} is equivalent to
\sphinxcode{\sphinxupquote{move=> ? ?}} on a goal such as:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall x y, x \PYGZlt{} y \PYGZhy{}\PYGZgt{} G
\end{sphinxVerbatim}

\sphinxAtStartPar
A typical use if \sphinxcode{\sphinxupquote{move=>> H}} to name \sphinxcode{\sphinxupquote{H}} the first assumption,
in the example above \sphinxcode{\sphinxupquote{x < y}}.

\item[{\sphinxcode{\sphinxupquote{?}}}] \leavevmode
\sphinxAtStartPar
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}[38]\sphinxAtStartFootnote
\DUrole{smallcaps}{SSReflect} reserves all identifiers of the form “\_x\_”, which is
used for such generated names.
%
\end{footnote}.

\item[{\sphinxcode{\sphinxupquote{\_}}}] \leavevmode
\sphinxAtStartPar
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{=>}} 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
\sphinxAtStartPar
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=> *}} tactic, e.g., on the goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall a b : bool, a \PYGZlt{}\PYGZgt{} b
\end{sphinxVerbatim}

\sphinxAtStartPar
a first \sphinxcode{\sphinxupquote{move=> *}} adds only \sphinxcode{\sphinxupquote{\_a\_ : bool}} and \sphinxcode{\sphinxupquote{\_b\_ : bool}}
to the context; it takes a second \sphinxcode{\sphinxupquote{move=> *}} to add \sphinxcode{\sphinxupquote{\_Hyp\_ : \_a\_ = \_b\_}}.

\item[{\sphinxcode{\sphinxupquote{+}}}] \leavevmode
\sphinxAtStartPar
temporarily introduces the top variable. It is discharged at the end
of the intro pattern. For example \sphinxcode{\sphinxupquote{move=> + y}} on a goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall x y, P
\end{sphinxVerbatim}

\sphinxAtStartPar
is equivalent to \sphinxcode{\sphinxupquote{move=> \_x\_ y; move: \_x\_}} that results in the goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall x, P
\end{sphinxVerbatim}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{occ\_switch}\DUrole{notation-sup}{?}} \sphinxhyphen{}>}}}}] \leavevmode
\sphinxAtStartPar
(resp. {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} \sphinxcode{\sphinxupquote{<\sphinxhyphen{}}})
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{| … |}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} * \sphinxcode{\sphinxupquote{{]}}}}] \leavevmode
\sphinxAtStartPar
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{=>}} 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
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item$_{\text{i}}$}}}}}}} on the i\sphinxhyphen{}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 the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_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{| … |}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} * \sphinxcode{\sphinxupquote{{]}}}}] \leavevmode
\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item$_{\text{i}}$}}}}}}}  in the i\sphinxhyphen{}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}[39]\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{\sphinxhyphen{}}}}] \leavevmode
\sphinxAtStartPar
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{| … |}}
{\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=> \sphinxhyphen{}{[}H1 H2{]}}}. It
can also be used to indicate explicitly the link between a view and a name
like in \sphinxcode{\sphinxupquote{move=> /eqP\sphinxhyphen{}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}[41]\sphinxAtStartFootnote
The current state of the proof shall be displayed by the Show
Proof command of Coq proof mode.
%
\end{footnote} explains in which
respect the tactic \sphinxcode{\sphinxupquote{move=> /v1/v2}} differs from the tactic \sphinxcode{\sphinxupquote{move=>
/v1\sphinxhyphen{}/v2}}.

\item[{\sphinxcode{\sphinxupquote{{[}:}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} \sphinxcode{\sphinxupquote{…{]}}}}] \leavevmode
\sphinxAtStartPar
introduces in the context an abstract constant
for each {\hyperref[\detokenize{language/core/basic: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{<hidden>}}.

\end{description}

\sphinxAtStartPar
Note that \DUrole{smallcaps}{SSReflect} does not support the syntax \sphinxcode{\sphinxupquote{(ipat, …, ipat)}} for
destructing intro patterns.


\subparagraph{Clear switch}
\label{\detokenize{proof-engine/ssreflect-proof-language:clear-switch}}
\sphinxAtStartPar
Clears are deferred until the end of the intro pattern.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
If the cleared names are reused in the same intro pattern, a renaming
is performed behind the scenes.

\sphinxAtStartPar
Facts mentioned in a clear switch must be valid names in the proof
context (excluding the section context).


\subparagraph{Branching and destructuring}
\label{\detokenize{proof-engine/ssreflect-proof-language:branching-and-destructuring}}
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{move=> {[}a b{]}.}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{case=> {[}a b{]}.}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{case=> a b.}}

\end{itemize}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{case=> {[}{]} {[}a b{]} c.}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{move=> {[}{[}a b{]} c{]}.}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{case; case=> a b c.}}

\end{itemize}

\sphinxAtStartPar
are all equivalent.


\subparagraph{Block introduction}
\label{\detokenize{proof-engine/ssreflect-proof-language:block-introduction}}
\sphinxAtStartPar
\DUrole{smallcaps}{SSReflect} supports the following {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_block}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_block}}}}}s:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\textasciicircum{} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
\sphinxstyleemphasis{block destructing} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}}. It performs a case analysis
on the top variable and introduces, in one go, all the variables coming
from the case analysis. The names of these variables are obtained by
taking the names used in the inductive type declaration and prefixing them
with {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. If the intro pattern immediately follows a call
to \sphinxcode{\sphinxupquote{elim}} with a custom eliminator (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:custom-elim-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Interpreting eliminations}}}}) then
the names are taken from the ones used in the type of the eliminator.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Record} \PYG{n}{r} \PYG{o}{:=} \PYG{o}{\PYGZob{}} \PYG{n}{a} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{;} \PYG{n}{b} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,} \PYG{l+m+mi}{3}\PYG{o}{)}\PYG{o}{;} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{;} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{r} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{a} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{b} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{r} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k}{move} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{o}{\PYGZca{}} \PYG{n}{x} \PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{xa} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{xb} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{xa}\PYG{o}{,} \PYG{l+m+mi}{3}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{*} \PYG{n}{nat}
      \PYG{o}{\PYGZus{}}\PYG{n}{x}\PYG{o}{?}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{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}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\textasciicircum{}\textasciitilde{} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
\sphinxstyleemphasis{block destructing} using {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} as a suffix.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\textasciicircum{}\textasciitilde{} {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
\sphinxstyleemphasis{block destructing} using {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} as a suffix.

\sphinxAtStartPar
Only a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} is allowed between the elimination tactic and
the block destructing.

\end{description}


\paragraph{Generation of equations}
\label{\detokenize{proof-engine/ssreflect-proof-language:generation-of-equations}}\label{\detokenize{proof-engine/ssreflect-proof-language:generation-of-equations-ssr}}
\sphinxAtStartPar
The generation of named equations option stores the definition of a
new constant as an equation. The tactic:

\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}

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:}\PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{[|}\PYG{n}{n}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal} \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}

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:}\PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal} \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}{goal} \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{n}{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}

\sphinxAtStartPar
Combining the generation of named equations mechanism with the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}}
tactic strengthens the power of a case analysis. On the other hand,
when combined with the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.elim}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim}}}}} tactic, this feature is mostly useful for
debug purposes, to trace the values of decomposed parameters and
pinpoint failing branches.


\paragraph{Type families}
\label{\detokenize{proof-engine/ssreflect-proof-language:type-families}}\label{\detokenize{proof-engine/ssreflect-proof-language:type-families-ssr}}
\sphinxAtStartPar
When the top assumption of a goal has an inductive type, two specific
operations are possible: the case analysis performed by the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}}
tactic, and the application of an induction principle, performed by
the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.elim}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim}}}}} tactic. When this top assumption has an inductive type, which
is moreover an instance of a type family, Coq may need help from the
user to specify which occurrences of the parameters of the type should
be substituted.


\begin{savenotes}\begin{fulllineitems}
\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}{+}}}}}}\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}{+}}}}}}
\sphinxAtStartPar
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.
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.

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}

\sphinxAtStartPar
Here is a small example on lists. We define first a function which
adds an element at the end of a given list.

\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{n}{list} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Fixpoint} \PYG{n}{add\PYGZus{}last} \PYG{n}{a} \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
 \PYG{o}{|} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{a} \PYG{o}{::} \PYG{n}{nil}
 \PYG{o}{|} \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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
Then we define an inductive predicate for case analysis on lists
according to their last element:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{last\PYGZus{}spec} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{LastSeq0} \PYG{o}{:} \PYG{n}{last\PYGZus{}spec} \PYG{n}{nil}
\PYG{o}{|} \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{n}{last\PYGZus{}spec\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Theorem} \PYG{n}{lastP} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}\PYG{o}{,} \PYG{n}{last\PYGZus{}spec} \PYG{n}{l}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \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{n}{last\PYGZus{}spec} \PYG{n}{l}

\PYG{k+kn}{Admitted}\PYG{o}{.}
    \PYG{n}{lastP} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

\sphinxAtStartPar
We are now ready to use \sphinxcode{\sphinxupquote{lastP}} in conjunction with \sphinxcode{\sphinxupquote{case}}.

\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}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Applied to the same goal, the tactc \sphinxcode{\sphinxupquote{case: l / (lastP l)}}
generates the same subgoals but \sphinxcode{\sphinxupquote{l}} has been cleared from both contexts:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{case}\PYG{o}{:} \PYG{n}{l} \PYG{o}{/} \PYG{o}{(}\PYG{n}{lastP} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \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{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Again applied to the same goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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}{goals}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
The equation name generation feature combined with a type family \sphinxcode{\sphinxupquote{/}}
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}

\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}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{[|}\PYG{n}{s} \PYG{n}{x}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{goal} \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}{goal} \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{n}{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}

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{/}} 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.

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

\end{fulllineitems}\end{savenotes}



\subsubsection{Control flow}
\label{\detokenize{proof-engine/ssreflect-proof-language:control-flow}}

\paragraph{Indentation and bullets}
\label{\detokenize{proof-engine/ssreflect-proof-language:indentation-and-bullets}}\label{\detokenize{proof-engine/ssreflect-proof-language:indentation-ssr}}
\sphinxAtStartPar
A linear development of 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.

\sphinxAtStartPar
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{\sphinxhyphen{}}}, \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.

\sphinxAtStartPar
Here is a fragment of such a structured script:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
case E1: (abezoutn \PYGZus{} \PYGZus{}) =\PYGZgt{} [[| k1] [| 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{}| 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{} [| [| s1]].
\PYGZhy{} rewrite muln0 gexpn0 mul1g =\PYGZgt{} H1.
...
\end{sphinxVerbatim}


\paragraph{Terminators}
\label{\detokenize{proof-engine/ssreflect-proof-language:terminators}}\label{\detokenize{proof-engine/ssreflect-proof-language:terminators-ssr}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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 {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.contradiction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{contradiction}}}}} or {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assumption}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assumption}}}}}.

\sphinxAtStartPar
In fact, \DUrole{smallcaps}{SSReflect} provides a generic tactical which turns any tactic
into a closing one (similar to {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.now}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{now}}}}}). Its general syntax is:
\index{by (tactic)@\spxentry{by}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.by}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
The Ltac expression \sphinxcode{\sphinxupquote{\DUrole{notation}{by {[}{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} | {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} | …{]}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{do {[}done | by {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} | by {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} | …{]}}}}, which corresponds to the
standard Ltac expression \sphinxcode{\sphinxupquote{\DUrole{notation}{first {[}done | {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}; done | {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}; done | …{]}}}}.

\sphinxAtStartPar
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\sphinxhyphen{}case ends with a tactic line prefixed
with a \sphinxcode{\sphinxupquote{by}}, like in:

\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 (tactic)@\spxentry{done}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.done}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{done}}}}
\sphinxAtStartPar
The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.by}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{by}}}}} tactical is implemented using the user\sphinxhyphen{}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 {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}; done}}}.

\sphinxAtStartPar
Conversely, the tactic \sphinxcode{\sphinxupquote{by {[} {]}}} is equivalent to {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.done}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{done}}}}}.

\sphinxAtStartPar
The default implementation of the done tactic, in the \sphinxcode{\sphinxupquote{ssreflect.v}}
file, is:

\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}{|} \PYG{k}{apply}\PYG{o}{:} \PYG{n}{sym\PYGZus{}equal}\PYG{o}{;} \PYG{k}{trivial}\PYG{o}{]}
         \PYG{o}{|} \PYG{k+kp}{discriminate} \PYG{o}{|} \PYG{k+kp}{contradiction} \PYG{o}{|} \PYG{k}{split}\PYG{o}{]}
   \PYG{o}{|} \PYG{k}{case} \PYG{n}{not\PYGZus{}locked\PYGZus{}false\PYGZus{}eq\PYGZus{}true}\PYG{o}{;} \PYG{k+kp}{assumption}
   \PYG{o}{|} \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZti{}} \PYG{o}{\PYGZus{}} \PYG{o}{|}\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}

\sphinxAtStartPar
The lemma \sphinxcode{\sphinxupquote{\DUrole{name}{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 {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} tactic.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{exact}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
is equivalent to:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kr}{do} \PYG{o}{[}\PYG{k+kp}{done} \PYG{o}{|} \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}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{top}} is a fresh name assigned to the top assumption of the goal.
This applied form is supported by the \sphinxcode{\sphinxupquote{:}} discharge tactical, and the
tactic:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{exact}\PYG{o}{:} \PYG{n}{MyLemma}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
is equivalent to:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{by} \PYG{k}{apply}\PYG{o}{:} \PYG{n}{MyLemma}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
(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:}
\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{by} \PYG{k}{rewrite} \PYG{n}{my\PYGZus{}lemma1}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
succeeds, then the tactic:

\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}

\sphinxAtStartPar
usually fails since it is equivalent to:

\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}


\paragraph{Selectors}
\label{\detokenize{proof-engine/ssreflect-proof-language:selectors}}\label{\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}}\index{last (tactic)@\spxentry{last}\spxextra{tactic}}\index{first (ssreflect) (tactic)@\spxentry{first (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.last}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{last}}}}\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.first-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{first}}}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} ; last by {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}
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 \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} ; first by {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}
tries to solve the first subgoal generated by the first tactic using the
second given tactic, and fails if it does not succeed.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
\DUrole{smallcaps}{SSReflect} also offers an extension of this facility, by supplying
tactics to \sphinxstyleemphasis{permute} the subgoals generated by a tactic.
\index{last first (tactic variant)@\spxentry{last first}\spxextra{tactic variant}}\index{first last (tactic variant)@\spxentry{first last}\spxextra{tactic variant}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.last-first}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{last~first}}}}\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.first-last}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{first~last}}}}
\sphinxAtStartPar
These two equivalent tactics invert the order of the subgoals in focus.


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{last~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~first}}}}
\sphinxAtStartPar
If {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}'s value is \(k\),
this tactic rotates the \(n\) subgoals \(G_1\) , …, \(G_n\)
in focus. Subgoal \(G_{n + 1 − k}\) becomes the first, and the
circular order of subgoals remains unchanged.

\end{fulllineitems}\end{savenotes}

\index{first (ssreflect) (tactic)@\spxentry{first (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id11}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{first~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~last}}}}
\sphinxAtStartPar
If {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}'s value is \(k\),
this tactic rotates the \(n\) subgoals \(G_1\) , …, \(G_n\)
in focus. Subgoal \(G_{k + 1 \bmod n}\) becomes the first, and the circular order
of subgoals remains unchanged.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
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

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{tactic} \PYG{o}{;} \PYG{k+kr}{last} \PYG{n}{k} \PYG{o}{[} \PYG{n}{tactic1} \PYG{o}{|}\PYG{n+nb+bp}{…}\PYG{o}{|} \PYG{n}{tacticm} \PYG{o}{]} \PYG{o}{|}\PYG{o}{|} \PYG{n}{tacticn}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
where natural denotes the integer \(k\) as above, applies tactic1 to the
\(n−k+1\)\sphinxhyphen{}th goal, … tacticm to the \(n−k+2\)\sphinxhyphen{}th goal and tacticn
to the others.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Here is a small example on lists. We define first a function which
adds an element at the end of a given list.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{test} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{|} \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}{|} \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}{|} \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}{|} \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{n}{test\PYGZus{}sind} \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}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{|} \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}{goals}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{n0} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
    
    \PYG{n}{goal} \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}{goal} \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}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{n}{n0} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n0} \PYG{o}{=} \PYG{l+m+mi}{4} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Iteration}
\label{\detokenize{proof-engine/ssreflect-proof-language:iteration}}\label{\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}}\index{do (ssreflect) (tactic)@\spxentry{do (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.do-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[}~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}~{]}}}}}}}
\sphinxAtStartPar
This tactical offers an accurate control on the repetition of tactics.
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{mult}}}}} is a \sphinxstyleemphasis{multiplier}.

\sphinxAtStartPar
Brackets can only be omitted if a single tactic is given \sphinxstyleemphasis{and} a
multiplier is present.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
A tactic of the form:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kr}{do} \PYG{o}{[} \PYG{n}{tactic} \PYG{l+m+mi}{1} \PYG{o}{|} \PYG{n+nb+bp}{…} \PYG{o}{|} \PYG{n}{tactic} \PYG{n}{n} \PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
is equivalent to the standard Ltac expression:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kr}{first} \PYG{o}{[} \PYG{n}{tactic} \PYG{l+m+mi}{1} \PYG{o}{|} \PYG{n+nb+bp}{…} \PYG{o}{|} \PYG{n}{tactic} \PYG{n}{n} \PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
There are four kinds of multipliers:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\DUrole{hole}{mult}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}} !}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{!}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}} ?}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Their meaning is:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{n!}} the step tactic is repeated exactly n times (where n is a
positive integer argument).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{!}} the step tactic is repeated as many times as possible, and done
at least once.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{?}} the step tactic is repeated as many times as possible,
optionally.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{n?}} the step tactic is repeated up to n times, optionally.

\end{itemize}

\sphinxAtStartPar
For instance, the tactic:

\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}

\sphinxAtStartPar
rewrites at most one time the lemma \sphinxcode{\sphinxupquote{mult\_comm}} in all the subgoals
generated by tactic, whereas the tactic:

\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}}}}.


\paragraph{Localization}
\label{\detokenize{proof-engine/ssreflect-proof-language:localization}}\label{\detokenize{proof-engine/ssreflect-proof-language:localization-ssr}}
\sphinxAtStartPar
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 (tactic)@\spxentry{in}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.in}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
where {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a name in the
context. On the left side of \sphinxcode{\sphinxupquote{in}},
{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\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}}}}).

\sphinxAtStartPar
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.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{in}} tactical successively:
\begin{itemize}
\item {} 
\sphinxAtStartPar
generalizes the selected hypotheses, possibly “protecting” the goal
if \sphinxcode{\sphinxupquote{*}} is not present,

\item {} 
\sphinxAtStartPar
performs {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic}}}}}, on the obtained goal,

\item {} 
\sphinxAtStartPar
reintroduces the generalized facts, under the same names.

\end{itemize}

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
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.}}


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{(~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~)}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{(~\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}{\hyperref[\detokenize{language/core/basic: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}{?}}}}}}
\sphinxAtStartPar
This is the most general form of the \sphinxcode{\sphinxupquote{in}} tactical.
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}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Structure}
\label{\detokenize{proof-engine/ssreflect-proof-language:structure}}\label{\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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.


\subparagraph{The have tactic.}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-have-tactic}}\index{have (tactic)@\spxentry{have}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.have}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~:~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This is the main \DUrole{smallcaps}{SSReflect} forward reasoning tactic. It can
be used 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.

\sphinxAtStartPar
This tactic supports open syntax for {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. Applied to a goal \sphinxcode{\sphinxupquote{G}}, it
generates a first subgoal requiring a proof of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} in the context of
\sphinxcode{\sphinxupquote{G}}. The second generated subgoal is of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{term \sphinxhyphen{}> G}}}, where term
becomes the new top assumption, instead of being introduced with a
fresh name. At the proof\sphinxhyphen{}term level, the have tactic creates a β
redex, and introduces the lemma under a fresh name, automatically
chosen.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Like in the case of the \sphinxcode{\sphinxupquote{\DUrole{notation}{pose <pose (ssreflect)>}}} 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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
The invocation of \sphinxcode{\sphinxupquote{have}} is equivalent to:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
The have tactic also enjoys the same abstraction mechanism as the \sphinxcode{\sphinxupquote{pose}}
tactic for the non\sphinxhyphen{}inferred implicit arguments. For instance, the
tactic:

\begin{sphinxadmonition}{note}{Example}

\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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goal} \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{n}{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}

\sphinxAtStartPar
opens a new subgoal where the type of \sphinxcode{\sphinxupquote{x}} is quantified.
\end{sphinxadmonition}

\sphinxAtStartPar
The behavior of the defective have tactic makes it possible to
generalize it in the following general construction:
\index{have (tactic)@\spxentry{have}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id12}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Open syntax is supported for both {\hyperref[\detokenize{language/core/basic: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\sphinxhyphen{}proof for an intermediate result, uses
tactics of the form:


\begin{savenotes}\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
which behave like:

\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}

\sphinxAtStartPar
Note that the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} \sphinxstyleemphasis{precedes} the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{by}} feature is especially convenient when the proof script of the
statement is very short, basically when it fits in one line like in:

\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}

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{n}{a} \PYG{o}{=} \PYG{n}{a}
    
    \PYG{n}{goal} \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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
Thanks to the deferred execution of clears, the following idiom is
also supported (assuming x occurs in the goal only):

\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}

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{;} \PYG{k+kr}{last} \PYG{k+kr}{first}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{exists} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
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{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic creates a new assumption of type the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.
If the
optional {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is present, this assumption is introduced under the
name {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. Note that the body of the constant is lost for the user.

\sphinxAtStartPar
Again, non inferred implicit arguments and explicit holes are
abstracted.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
      
      \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}

\sphinxAtStartPar
adds to the context \sphinxcode{\sphinxupquote{H : Type \sphinxhyphen{}> 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}

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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{n}{lia}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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:

\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{n}{lia}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{nat}\PYG{o}{,} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{x} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.have}]{\sphinxcrossref{\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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{k+kr}{last} \PYG{k+kr}{first}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \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}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\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}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that H is introduced in the second goal.
\end{sphinxadmonition}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{suff}} modifier is not
compatible with the presence of a list of binders.


\subparagraph{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}}
\sphinxAtStartPar
Since \DUrole{smallcaps}{SSReflect} 1.5 the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.have}]{\sphinxcrossref{\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}

\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{n}{Ord\PYGZus{}sind} \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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{lia}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{ZifyClasses}\PYG{o}{.}\PYG{n}{rew\PYGZus{}iff\PYGZus{}rev} \PYG{o}{(}\PYG{n}{m} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Z}\PYG{o}{.}\PYG{n}{of\PYGZus{}nat} \PYG{n}{m} \PYG{o}{\PYGZlt{}} \PYG{n}{Z}\PYG{o}{.}\PYG{n}{of\PYGZus{}nat} \PYG{n}{n}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}
                \PYG{o}{(}\PYG{n}{ZifyClasses}\PYG{o}{.}\PYG{n}{mkrel} \PYG{n}{nat} \PYG{n}{Z} \PYG{n}{lt} \PYG{n}{Z}\PYG{o}{.}\PYG{n}{of\PYGZus{}nat} \PYG{n}{Z}\PYG{o}{.}\PYG{n}{lt} \PYG{n}{Nat2Z}\PYG{o}{.}\PYG{n}{inj\PYGZus{}lt} \PYG{n}{m} 
                   \PYG{o}{(}\PYG{o}{..}\PYG{o}{.}\PYG{o}{)} \PYG{n}{eq\PYGZus{}refl} \PYG{n}{n} \PYG{o}{(}\PYG{o}{..}\PYG{o}{.}\PYG{o}{)} \PYG{n}{eq\PYGZus{}refl}\PYG{o}{)}
                \PYG{o}{(}\PYG{k}{let} \PYG{n}{H0} \PYG{o}{:} \PYG{o}{..}\PYG{o}{.}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{o}{:=} \PYG{o}{..}\PYG{o}{.} \PYG{k}{in} \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}

\sphinxAtStartPar
Note that the subterm produced by {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} 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}

\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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{lia}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

  \PYG{k+kp}{by} \PYG{n}{lia}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{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{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}

\sphinxAtStartPar
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).

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{lia}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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{n}{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{n}{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{n}{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}

\sphinxAtStartPar
Last, notice that the use of intro patterns for abstract constants is
orthogonal to the transparent flag \sphinxcode{\sphinxupquote{@}} for have.


\subparagraph{The have tactic and typeclass resolution}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-have-tactic-and-typeclass-resolution}}
\sphinxAtStartPar
Since \DUrole{smallcaps}{SSReflect} 1.5 the \sphinxcode{\sphinxupquote{have}} tactic behaves as follows with respect to
typeclass inference.
\begin{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{foo} \PYG{o}{:} \PYG{n}{ty}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{ty}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
\end{sphinxVerbatim}

\sphinxAtStartPar
Full inference for \sphinxcode{\sphinxupquote{ty}}. The first subgoal demands a
proof of such instantiated statement.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{foo} \PYG{o}{:} \PYG{n}{ty} \PYG{o}{:=} \PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{foo} \PYG{o}{:} \PYG{n}{ty} \PYG{o}{:=} \PYG{n}{t}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{foo} \PYG{o}{:} \PYG{n}{ty}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\sphinxAtStartPar
No inference for \sphinxcode{\sphinxupquote{ty}} and \sphinxcode{\sphinxupquote{t}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{foo} \PYG{o}{:=} \PYG{n}{t}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{foo} \PYG{o}{:} \PYG{n}{ty}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\sphinxAtStartPar
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{quote}
\index{SsrHave NoTCResolution (flag)@\spxentry{SsrHave NoTCResolution}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} restores the behavior of \DUrole{smallcaps}{SSReflect} 1.4 and below (never resolve typeclasses).

\end{fulllineitems}\end{savenotes}



\subparagraph{Variants: the suff and wlog tactics}
\label{\detokenize{proof-engine/ssreflect-proof-language:variants-the-suff-and-wlog-tactics}}
\sphinxAtStartPar
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 …”.

\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
the order of the generated subgoals is inverted

\item {} 
\sphinxAtStartPar
the optional clear item is still performed in the \sphinxstyleemphasis{second}
branch. This means that the tactic:

\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{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
fails if the context of the current goal indeed contains an
assumption named \sphinxcode{\sphinxupquote{H}}.

\end{itemize}

\sphinxAtStartPar
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.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{have}} modifier can follow the \sphinxcode{\sphinxupquote{suff}} tactic.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{G}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \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}{goal} \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}

\sphinxAtStartPar
Note that, in contrast with \sphinxcode{\sphinxupquote{have suff}}, the name H has been introduced
in the first goal.
\end{sphinxadmonition}

\sphinxAtStartPar
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 \sphinxhyphen{}> G}}. Hence the user shall
provide a proof for both \sphinxcode{\sphinxupquote{(wlog\_statement \sphinxhyphen{}> G) \sphinxhyphen{}> G}} and
\sphinxcode{\sphinxupquote{wlog\_statement \sphinxhyphen{}> 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.

\sphinxAtStartPar
\DUrole{smallcaps}{SSReflect} implements this kind of reasoning step through the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.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 (tactic)@\spxentry{wlog}\spxextra{tactic}}\index{without loss (tactic)@\spxentry{without loss}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.wlog}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}~/~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.without-loss}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}~/~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
where each {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a constant in the context
of the goal. Open syntax is supported for {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\sphinxAtStartPar
In its defective form:


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{wlog:~/~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{without~loss:~/~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
on a goal G, it creates two subgoals: a first one to prove the
formula (term \sphinxhyphen{}> G) \sphinxhyphen{}> G and a second one to prove the formula
term \sphinxhyphen{}> G.

\sphinxAtStartPar
If the optional list of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is present
on the left side of \sphinxcode{\sphinxupquote{/}}, these constants are generalized in the
premise (term \sphinxhyphen{}> 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.

\sphinxAtStartPar
In the second subgoal, the tactic:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{clear\PYGZus{}switch} \PYG{n}{i\PYGZus{}item}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}

\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}{goal}
      
      \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{n}{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}{goals}
      
      \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{n}{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{n}{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}{goal} \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}{goal}
      
      \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{n}{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}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{wlog suff}} variant is simpler, since it cuts \sphinxcode{\sphinxupquote{wlog\_statement}} instead
of \sphinxcode{\sphinxupquote{wlog\_statement \sphinxhyphen{}> G}}. It thus opens the goals
\sphinxcode{\sphinxupquote{wlog\_statement \sphinxhyphen{}> G}}
and \sphinxcode{\sphinxupquote{wlog\_statement}}.

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{k+kr}{last} \PYG{k+kr}{first}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{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}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\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}{)}
\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}}
\sphinxAtStartPar
The complete syntax for the items on the left hand side of the \sphinxcode{\sphinxupquote{/}}
separator is the following one:


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{wlog~…~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{(~\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Clear operations are intertwined with generalization operations. This
helps in particular avoiding dependency issues while generalizing some
facts.

\sphinxAtStartPar
If an {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is prefixed with the \sphinxcode{\sphinxupquote{@}} mark, then a let\sphinxhyphen{}in redex is
created, which keeps track if its body (if any). The syntax
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{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.

\sphinxAtStartPar
The syntax \sphinxcode{\sphinxupquote{(@x := y)}} generates a let\sphinxhyphen{}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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Test}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{twoy}
\end{sphinxVerbatim}

\sphinxAtStartPar
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

\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}{goals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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{n}{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}{goal} \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}


\subsubsection{Rewriting}
\label{\detokenize{proof-engine/ssreflect-proof-language:rewriting}}\label{\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}}
\sphinxAtStartPar
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.


\paragraph{An extended rewrite tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:an-extended-rewrite-tactic}}
\sphinxAtStartPar
The main features of the rewrite tactic are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
It can perform an entire series of such operations in any subset of
the goal and/or context;

\item {} 
\sphinxAtStartPar
It allows to perform rewriting, simplifications, folding/unfolding
of definitions, closing of goals;

\item {} 
\sphinxAtStartPar
Several rewriting operations can be chained in a single tactic;

\item {} 
\sphinxAtStartPar
Control over the occurrence at which rewriting is to be performed is
significantly enhanced.

\end{itemize}

\sphinxAtStartPar
The general form of an \DUrole{smallcaps}{SSReflect} rewrite tactic is:
\index{rewrite (ssreflect) (tactic)@\spxentry{rewrite (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.rewrite-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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}\end{savenotes}


\sphinxAtStartPar
The combination of a rewrite tactic with the \sphinxcode{\sphinxupquote{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.

\sphinxAtStartPar
A rewrite step {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-rstep}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rstep}}}}} has the general form:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-rstep}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-rstep}]{\sphinxcrossref{\DUrole{hole}{rstep}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\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}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}]{\sphinxcrossref{\DUrole{hole}{r\_prefix}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\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}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\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}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\DUrole{hole}{r\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\DUrole{hole}{r\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{/}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
The optional initial \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} 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\sphinxhyphen{}to\sphinxhyphen{}left and it is left\sphinxhyphen{}to\sphinxhyphen{}right otherwise.

\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Selectors}}}}) or a
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}),
these two possibilities being exclusive.

\sphinxAtStartPar
An occurrence switch selects
the occurrences of the rewrite pattern which should be affected by the
rewrite operation.

\sphinxAtStartPar
A clear switch, even an empty one, is performed \sphinxstyleemphasis{after} the
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}} is actually processed and is complemented with the name of
the rewrite rule if an only if it is a simple proof context entry \sphinxfootnotemark[42].
As a consequence one can
write \sphinxcode{\sphinxupquote{rewrite \{\}H}} to rewrite with \sphinxcode{\sphinxupquote{H}} and dispose \sphinxcode{\sphinxupquote{H}} immediately
afterwards.
This behavior can be avoided by putting parentheses around the rewrite rule.

\end{itemize}

\sphinxAtStartPar
An {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}} can be:
\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 \sphinxhyphen{}/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 \sphinxhyphen{}{[}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/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, which can be:}] \leavevmode\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 | … | rewrite r\_prefix tn {]}.}}

\item {} 
\sphinxAtStartPar
An anonymous rewrite lemma \sphinxcode{\sphinxupquote{(\_ : term)}}, where term has a type as above.

\end{itemize}

\end{description}

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{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:}
\sphinxAtStartPar
The \DUrole{smallcaps}{SSReflect} terms containing holes are \sphinxstyleemphasis{not} typed as
abstractions in this context. Hence the following script fails.

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\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}{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}

\sphinxAtStartPar
but the following script succeeds

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}
\index{SsrOldRewriteGoalsOrder (flag)@\spxentry{SsrOldRewriteGoalsOrder}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:flag.SsrOldRewriteGoalsOrder}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SsrOldRewriteGoalsOrder}}}}
\sphinxAtStartPar
Controls the order in which generated subgoals (side conditions)
are added to the
proof context.  The {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is off by default, which puts subgoals generated
by conditional rules first, followed by the main goal.  When it is on,
the main goal appears first.  If your proofs are organized to complete
proving the main goal before side conditions, turning the flag on will save you
from having to add {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.last-first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{last first}}}}} tactics that would be needed
to keep the main goal as the currently focused goal.

\end{fulllineitems}\end{savenotes}



\paragraph{Remarks and examples}
\label{\detokenize{proof-engine/ssreflect-proof-language:remarks-and-examples}}

\subparagraph{Rewrite redex selection}
\label{\detokenize{proof-engine/ssreflect-proof-language:rewrite-redex-selection}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
This may be a source of incompatibilities between the two rewrite
tactics.

\sphinxAtStartPar
In a rewrite tactic of the form:

\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}

\sphinxAtStartPar
\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 {} 
\sphinxAtStartPar
First \sphinxcode{\sphinxupquote{term1}} and \sphinxcode{\sphinxupquote{term2}} are βι 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 ζ reductions.

\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
Finally the goal is βι normalized.

\end{itemize}

\sphinxAtStartPar
In the case \sphinxcode{\sphinxupquote{term2}} is a list of terms, the first top\sphinxhyphen{}down (in the
goal) left\sphinxhyphen{}to\sphinxhyphen{}right (in the list) matching rule gets selected.


\subparagraph{Chained rewrite steps}
\label{\detokenize{proof-engine/ssreflect-proof-language:chained-rewrite-steps}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
Performing rewrite and simplification operations in a single tactic
enhances significantly the concision of scripts. For instance the
tactic:

\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
Here are some concrete examples of chained rewrite operations, in the
proof of basic results on natural numbers arithmetic.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n}\PYG{o}{,} \PYG{n}{p} \PYG{o}{:} \PYG{n}{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}{|} \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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}

\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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Note the use of the \sphinxcode{\sphinxupquote{?}} switch for parallel rewrite operations in the
proof of \sphinxcode{\sphinxupquote{addnCA}}.


\subparagraph{Explicit redex switches are matched first}
\label{\detokenize{proof-engine/ssreflect-proof-language:explicit-redex-switches-are-matched-first}}
\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{t} \PYG{n}{u} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{t} \PYG{n}{u} \PYG{o}{:} \PYG{n}{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{n}{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}

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{t} \PYG{n}{u} \PYG{o}{:} \PYG{n}{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{n}{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{n}{Fail} \PYG{k}{rewrite} \PYG{o}{[}\PYG{n}{x} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{]}\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{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}

\sphinxAtStartPar
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}


\subparagraph{Occurrence switches and redex switches}
\label{\detokenize{proof-engine/ssreflect-proof-language:occurrence-switches-and-redex-switches}}\label{\detokenize{proof-engine/ssreflect-proof-language:ssr-rewrite-occ-switch}}
\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{z} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{z}
    
    \PYG{n}{goal} \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}

\sphinxAtStartPar
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}}.


\subparagraph{Occurrence selection and repetition}
\label{\detokenize{proof-engine/ssreflect-proof-language:occurrence-selection-and-repetition}}
\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{(}\PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{z} \PYG{o}{=} \PYG{n}{z}
    \PYG{n}{goal} \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}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{z} \PYG{o}{=} \PYG{n}{z}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
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.


\subparagraph{Multi\sphinxhyphen{}rule rewriting}
\label{\detokenize{proof-engine/ssreflect-proof-language:multi-rule-rewriting}}
\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{n}{c} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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 Coq term and we can name it with a
definition:

\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}

\sphinxAtStartPar
In this case, the tactic \sphinxcode{\sphinxupquote{rewrite multi1}} is a synonym for
\sphinxcode{\sphinxupquote{rewrite (eqab, eqac)}}.
\end{sphinxadmonition}

\sphinxAtStartPar
More precisely, a multirule rewrites the first subterm to which one of
the rules applies in a left\sphinxhyphen{}to\sphinxhyphen{}right traversal of the goal, with the
first rule from the multirule tree in left\sphinxhyphen{}to\sphinxhyphen{}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}

\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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Indeed rule \sphinxcode{\sphinxupquote{eqd0}} applies without unfolding the
definition of \sphinxcode{\sphinxupquote{d}}.
\end{sphinxadmonition}

\sphinxAtStartPar
For repeated rewrites the selection process is
repeated anew.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{n}{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{n}{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{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{n}{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{n}{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{n}{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}

\sphinxAtStartPar
It uses \sphinxcode{\sphinxupquote{eq\_adda\_b}} then \sphinxcode{\sphinxupquote{eqb0}} on the left\sphinxhyphen{}hand
side only. Without the bound \sphinxcode{\sphinxupquote{2}} one would obtain \sphinxcode{\sphinxupquote{0 = 0}}.
\end{sphinxadmonition}

\sphinxAtStartPar
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}

\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}

\sphinxAtStartPar
except that the constants \sphinxcode{\sphinxupquote{eqba}}, \sphinxcode{\sphinxupquote{eqab}}, \sphinxcode{\sphinxupquote{mult1\_rev}}
have not been created.

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{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:

\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}

\sphinxAtStartPar
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}}:

\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}

\sphinxAtStartPar
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.


\subparagraph{Wildcards vs abstractions}
\label{\detokenize{proof-engine/ssreflect-proof-language:wildcards-vs-abstractions}}
\sphinxAtStartPar
The rewrite tactic supports {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}}s 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}

\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}{goal}
      
      \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal} \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}

\sphinxAtStartPar
while the other tactic results in

\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}{goals}
      
      \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{goal} \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}

\sphinxAtStartPar
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}


\subparagraph{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}}
\sphinxAtStartPar
In a few cases, the \DUrole{smallcaps}{SSReflect} rewrite tactic fails rewriting some
redexes which standard Coq successfully rewrites. There are two main
cases:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\DUrole{smallcaps}{SSReflect} never accepts to rewrite indeterminate patterns like:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{foo} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{unit}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{tt}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
\DUrole{smallcaps}{SSReflect} will however accept the
ηζ expansion of this rule:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{fubar} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{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 {} 
\sphinxAtStartPar
The standard rewrite tactic provided by Coq uses a different algorithm
to find instances of the rewrite rule.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{g} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}{goal}
      
      \PYG{n}{g} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}{goal}
      
      \PYG{n}{g} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}

\sphinxAtStartPar
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.

\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{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}

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{/}\PYG{n}{f} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{g} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}

\sphinxAtStartPar
alternatively one can override the pattern inferred from \sphinxcode{\sphinxupquote{H}}

\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}{goal}
      
      \PYG{n}{g} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}


\subparagraph{Existential metavariables and rewriting}
\label{\detokenize{proof-engine/ssreflect-proof-language:existential-metavariables-and-rewriting}}
\sphinxAtStartPar
The rewrite tactic will not instantiate existing existential
metavariables when matching a redex pattern.

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{leq} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{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{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{n}{Ord\PYGZus{}sind} \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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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.

\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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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.


\paragraph{Rewriting under binders}
\label{\detokenize{proof-engine/ssreflect-proof-language:rewriting-under-binders}}\label{\detokenize{proof-engine/ssreflect-proof-language:under-ssr}}
\sphinxAtStartPar
Goals involving objects defined with higher\sphinxhyphen{}order functions often
require "rewriting under binders". While setoid rewriting is a
possible approach in this case, it is common to use regular rewriting
along with dedicated extensionality lemmas. This may cause some
practical issues during the development of the corresponding scripts,
notably as we might be forced to provide the rewrite tactic with
complete terms, as shown by the simple example below.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{subnn} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{map} \PYG{o}{:} \PYG{o}{(}\PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{n}{nat}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{sumlist} \PYG{o}{:} \PYG{n}{list} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{eq\PYGZus{}map} \PYG{o}{:}
  \PYG{k}{forall} \PYG{n}{F1} \PYG{n}{F2} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{F1} \PYG{n}{n} \PYG{o}{=} \PYG{n}{F2} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{map} \PYG{n}{F1} \PYG{n}{l} \PYG{o}{=} \PYG{n}{map} \PYG{n}{F2} \PYG{n}{l}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{example\PYGZus{}map} \PYG{n}{l} \PYG{o}{:} \PYG{n}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{m}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{m}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

\sphinxAtStartPar
In this context, one cannot directly use \sphinxcode{\sphinxupquote{eq\_map}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{n}{eq\PYGZus{}map}\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}{rewrite} \PYG{n}{eq\PYGZus{}map}\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{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}{F2}\PYG{o}{.}
    \PYG{n}{Rule\PYGZsq{}s} \PYG{n}{type}\PYG{o}{:}
    \PYG{o}{(}\PYG{k}{forall} \PYG{n}{F1} \PYG{n}{F2} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{,}
     \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{F1} \PYG{n}{n} \PYG{o}{=} \PYG{n}{F2} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{map} \PYG{n}{F1} \PYG{n}{l} \PYG{o}{=} \PYG{n}{map} \PYG{n}{F2} \PYG{n}{l}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
as we need to explicitly provide the non\sphinxhyphen{}inferable argument \sphinxcode{\sphinxupquote{F2}},
which corresponds here to the term we want to obtain \sphinxstyleemphasis{after} the
rewriting step. In order to perform the rewrite step one has to
provide the term by hand as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq\PYGZus{}map} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}

  \PYG{k+kp}{by} \PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{m}\PYG{o}{;} \PYG{k}{rewrite} \PYG{n}{subnn}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

\sphinxAtStartPar
The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} tactic lets one perform the same operation in a more
convenient way:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{example\PYGZus{}map} \PYG{n}{l} \PYG{o}{:} \PYG{n}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{m}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{m}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{n}{under} \PYG{n}{eq\PYGZus{}map} \PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{k+kr}{do} \PYG{k}{rewrite} \PYG{n}{subnn}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subparagraph{The under tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-under-tactic}}
\sphinxAtStartPar
The convenience {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} tactic supports the following syntax:
\index{under (tactic)@\spxentry{under}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{under~\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\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{repeat-wrapper}{\DUrole{repeat}{do~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[}~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}}~{]}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Operate under the context proved to be extensional by
lemma {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.
\index{Incorrect number of tactics (expected N tactics, was given M) (error)@\spxentry{Incorrect number of tactics (expected N tactics, was given M)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:exn.Incorrect-number-of-tactics-(expected-N-tactics,-was-given-M)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Incorrect~number~of~tactics~(expected~N~tactics,~was~given~M).}}}}
\sphinxAtStartPar
This error can occur when using the version with a \sphinxcode{\sphinxupquote{do}} clause.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
The multiplier part of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_prefix}}}}} is not supported.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
We distinguish two modes,
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:under-interactive}]{\sphinxcrossref{\DUrole{std,std-ref}{interactive mode}}}} without a \sphinxcode{\sphinxupquote{do}} clause, and
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:under-one-liner}]{\sphinxcrossref{\DUrole{std,std-ref}{one\sphinxhyphen{}liner mode}}}} with a \sphinxcode{\sphinxupquote{do}} clause,
which are explained in more detail below.


\subparagraph{Interactive mode}
\label{\detokenize{proof-engine/ssreflect-proof-language:interactive-mode}}\label{\detokenize{proof-engine/ssreflect-proof-language:under-interactive}}
\sphinxAtStartPar
Let us redo the running example in interactive mode.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{example\PYGZus{}map} \PYG{n}{l} \PYG{o}{:} \PYG{n}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{m}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{m}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{n}{under} \PYG{n}{eq\PYGZus{}map} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{focused} \PYG{n}{goals}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{2}\PYG{o}{)}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{nat}
      \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{\PYGZsq{}}\PYG{n}{Under}\PYG{o}{[} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{m} \PYG{o}{]}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}

  \PYG{k}{rewrite} \PYG{n}{subnn}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{focused} \PYG{n}{goals}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{2}\PYG{o}{)}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{nat}
      \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{\PYGZsq{}}\PYG{n}{Under}\PYG{o}{[} \PYG{l+m+mi}{0} \PYG{o}{]}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}

  \PYG{n}{over}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{goal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{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}{sumlist} \PYG{o}{(}\PYG{n}{map} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
The execution of the Ltac expression:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{under {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} => {[} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item$_{\text{1}}$}}}} | … | {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item$_{\text{n}}$}}}} {]}.}}}

\sphinxAtStartPar
involves the following steps:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
It performs a \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
without failing like in the first example with \sphinxcode{\sphinxupquote{rewrite eq\_map.}},
but creating evars (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.evar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{evar}}}}}). If \sphinxcode{\sphinxupquote{\DUrole{notation}{term}}} is prefixed by
a pattern or an occurrence selector, then the modifiers are honoured.

\item {} 
\sphinxAtStartPar
As a n\sphinxhyphen{}branches intro pattern is provided {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} checks that
n+1 subgoals have been created. The last one is the main subgoal,
while the other ones correspond to premises of the rewrite rule (such as
\sphinxcode{\sphinxupquote{forall n, F1 n = F2 n}} for \sphinxcode{\sphinxupquote{eq\_map}}).

\item {} 
\sphinxAtStartPar
If so {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} puts these n goals in head normal form (using
the defective form of the tactic {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.move-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move}}}}}), then executes
the corresponding intro pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern$_{\text{i}}$}}}}}}} in each goal.

\item {} 
\sphinxAtStartPar
Then {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} checks that the first n subgoals
are (quantified) Leibniz equalities, double implications or
registered relations (w.r.t. Class \sphinxcode{\sphinxupquote{RewriteRelation}}) between a
term and an evar, e.g. \sphinxcode{\sphinxupquote{m \sphinxhyphen{} m = ?F2 m}} in the running example.
(This support for setoid\sphinxhyphen{}like relations is enabled as soon as we do
both \sphinxcode{\sphinxupquote{Require Import ssreflect.}} and \sphinxcode{\sphinxupquote{Require Setoid.}})

\item {} 
\sphinxAtStartPar
If so {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} protects these n goals against an
accidental instantiation of the evar.
These protected goals are displayed using the \sphinxcode{\sphinxupquote{'Under{[} … {]}}}
notation (e.g. \sphinxcode{\sphinxupquote{'Under{[} m \sphinxhyphen{} m {]}}} in the running example).

\item {} 
\sphinxAtStartPar
The expression inside the \sphinxcode{\sphinxupquote{'Under{[} … {]}}} notation can be
proved equivalent to the desired expression
by using a regular {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} tactic.

\item {} 
\sphinxAtStartPar
Interactive editing of the first n goals has to be signalled by
using the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.over}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{over}}}}} tactic or rewrite rule (see below), which
requires that the underlying relation is reflexive. (The running
example deals with Leibniz equality, but \sphinxcode{\sphinxupquote{PreOrder}} relations are
also supported, for example.)

\item {} 
\sphinxAtStartPar
Finally, a post\sphinxhyphen{}processing step is performed in the main goal
to keep the name(s) for the bound variables chosen by the user in
the intro pattern for the first branch.

\end{enumerate}


\subparagraph{The over tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-over-tactic}}\label{\detokenize{proof-engine/ssreflect-proof-language:over-ssr}}
\sphinxAtStartPar
Two equivalent facilities (a terminator and a lemma) are provided to
close intermediate subgoals generated by {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} (i.e. goals
displayed as \sphinxcode{\sphinxupquote{'Under{[} … {]}}}):
\index{over (tactic)@\spxentry{over}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.over}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{over}}}}
\sphinxAtStartPar
This terminator tactic allows one to close goals of the form
\sphinxcode{\sphinxupquote{'Under{[} … {]}}}.

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{by~rewrite~over}}}}
\sphinxAtStartPar
This is a variant of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.over}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{over}}}}} in order to close \sphinxcode{\sphinxupquote{'Under{[} … {]}}}
goals, relying on the \sphinxcode{\sphinxupquote{over}} rewrite rule.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Note that a rewrite rule \sphinxcode{\sphinxupquote{UnderE}} is available as well, if one wants
to "unprotect" the evar, without closing the goal automatically (e.g.,
to instantiate it manually with another rule than reflexivity).


\subparagraph{One\sphinxhyphen{}liner mode}
\label{\detokenize{proof-engine/ssreflect-proof-language:one-liner-mode}}\label{\detokenize{proof-engine/ssreflect-proof-language:under-one-liner}}
\sphinxAtStartPar
The Ltac expression:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{under {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} => {[} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item$_{\text{1}}$}}}} | … | {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item$_{\text{n}}$}}}} {]} do {[} {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}} | … | {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{n}}$}}}} {]}.}}}

\sphinxAtStartPar
can be seen as a shorter form for the following expression:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{(under {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}) => {[} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item$_{\text{1}}$}}}} | … | {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item$_{\text{n}}$}}}} | {]}; {[} {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}}; over | … | {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{n}}$}}}}; over | cbv beta iota {]}.}}}

\sphinxAtStartPar
Notes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{beta\sphinxhyphen{}iota}} reduction here is useful to get rid of the beta
redexes that could be introduced after the substitution of the evars
by the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} tactic.

\item {} 
\sphinxAtStartPar
Note that the provided tactics can as well
involve other {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} tactics. See below for a typical example
involving the \sphinxcode{\sphinxupquote{bigop}} theory from the Mathematical Components library.

\item {} 
\sphinxAtStartPar
If there is only one tactic, the brackets can be omitted, e.g.:
\sphinxcode{\sphinxupquote{\DUrole{notation}{under {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} => i do {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}.}}} and that shorter form should be
preferred.

\item {} 
\sphinxAtStartPar
If the \sphinxcode{\sphinxupquote{do}} clause is provided and the intro pattern is omitted,
then the default {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} \sphinxcode{\sphinxupquote{*}} is applied to each branch.
E.g., the Ltac expression:
\sphinxcode{\sphinxupquote{\DUrole{notation}{under {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} do {[} {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}} | … | {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{n}}$}}}} {]}}}} is equivalent to:
\sphinxcode{\sphinxupquote{\DUrole{notation}{under {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} => {[} * | … | * {]} do {[} {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}} | … | {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{n}}$}}}} {]}}}}
(and it can be noted here that the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} tactic performs a
\sphinxcode{\sphinxupquote{move.}} before processing the intro patterns \sphinxcode{\sphinxupquote{=> {[} * | … | * {]}}}).

\end{itemize}

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{addnC} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{muln1} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{eq\PYGZus{}bigr}\PYG{o}{.}
    \PYG{n}{eq\PYGZus{}bigr}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{F1} \PYG{n}{F2} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{)}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{F1} \PYG{n}{x} \PYG{o}{=} \PYG{n}{F2} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{P} \PYG{n}{i}\PYG{o}{)} \PYG{n}{F1} \PYG{n}{i} \PYG{o}{=} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{P} \PYG{n}{i}\PYG{o}{)} \PYG{n}{F2} \PYG{n}{i}

\PYG{k+kn}{Check} \PYG{n}{eq\PYGZus{}big}\PYG{o}{.}
    \PYG{n}{eq\PYGZus{}big}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P1} \PYG{n}{P2} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{F1} \PYG{n}{F2} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{)}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{P1} \PYG{n}{x} \PYG{o}{=} \PYG{n}{P2} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{i} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{P1} \PYG{n}{i} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{F1} \PYG{n}{i} \PYG{o}{=} \PYG{n}{F2} \PYG{n}{i}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{P1} \PYG{n}{i}\PYG{o}{)} \PYG{n}{F1} \PYG{n}{i} \PYG{o}{=} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{P2} \PYG{n}{i}\PYG{o}{)} \PYG{n}{F2} \PYG{n}{i}


\PYG{k+kn}{Lemma} \PYG{n}{test\PYGZus{}big\PYGZus{}nested} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{:}
  \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{a} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{prime} \PYG{n}{a}\PYG{o}{)} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{j} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{|} \PYG{n}{odd} \PYG{o}{(}\PYG{n}{j} \PYG{o}{*} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{j}\PYG{o}{)} \PYG{o}{=}
  \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{prime} \PYG{n}{i}\PYG{o}{)} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{j} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{|} \PYG{n}{odd} \PYG{n}{j}\PYG{o}{)} \PYG{o}{(}\PYG{n}{j} \PYG{o}{+} \PYG{n}{i}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{a} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{prime} \PYG{n}{a}\PYG{o}{)} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{j} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{|} \PYG{n}{odd} \PYG{o}{(}\PYG{n}{j} \PYG{o}{*} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{j}\PYG{o}{)} \PYG{o}{=}
      \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{prime} \PYG{n}{i}\PYG{o}{)} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{j} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{|} \PYG{n}{odd} \PYG{n}{j}\PYG{o}{)} \PYG{o}{(}\PYG{n}{j} \PYG{o}{+} \PYG{n}{i}\PYG{o}{)}

\PYG{n}{under} \PYG{n}{eq\PYGZus{}bigr} \PYG{o}{=\PYGZgt{}} \PYG{n}{i} \PYG{n}{prime\PYGZus{}i} \PYG{k+kr}{do}
  \PYG{n}{under} \PYG{n}{eq\PYGZus{}big} \PYG{o}{=\PYGZgt{}} \PYG{o}{[} \PYG{n}{j} \PYG{o}{|} \PYG{n}{j} \PYG{n}{odd\PYGZus{}j} \PYG{o}{]} \PYG{k+kr}{do}
    \PYG{o}{[} \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{muln1} \PYG{n}{j}\PYG{o}{)} \PYG{o}{|} \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{addnC} \PYG{n}{i} \PYG{n}{j}\PYG{o}{)} \PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{prime} \PYG{n}{i}\PYG{o}{)} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{j} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{|} \PYG{n}{odd} \PYG{n}{j}\PYG{o}{)} \PYG{o}{(}\PYG{n}{j} \PYG{o}{+} \PYG{n}{i}\PYG{o}{)} \PYG{o}{=}
      \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{i} \PYG{o}{\PYGZlt{}} \PYG{n}{m} \PYG{o}{|} \PYG{n}{prime} \PYG{n}{i}\PYG{o}{)} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{sum\PYGZus{}}\PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{j} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{|} \PYG{n}{odd} \PYG{n}{j}\PYG{o}{)} \PYG{o}{(}\PYG{n}{j} \PYG{o}{+} \PYG{n}{i}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
Remark how the final goal uses the name \sphinxcode{\sphinxupquote{i}} (the name given in the
intro pattern) rather than \sphinxcode{\sphinxupquote{a}} in the binder of the first summation.
\end{sphinxadmonition}


\paragraph{Locking, unlocking}
\label{\detokenize{proof-engine/ssreflect-proof-language:locking-unlocking}}\label{\detokenize{proof-engine/ssreflect-proof-language:locking-ssr}}
\sphinxAtStartPar
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 {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}})
together with “term tagging” operations.

\sphinxAtStartPar
\DUrole{smallcaps}{SSReflect} provides two levels of tagging.

\sphinxAtStartPar
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 Coq system %
\begin{footnote}[40]\sphinxAtStartFootnote
This is an implementation feature: there is no such obstruction
in the metatheory
%
\end{footnote}. The job is done by the
following construction:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{master\PYGZus{}key} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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}

\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{n}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{guarded} \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}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{bool}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}

\sphinxAtStartPar
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}

\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{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}
\index{unlock (tactic)@\spxentry{unlock}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.unlock}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This tactic unfolds such definitions while removing “locks”, i.e. it
replaces the occurrence(s) of {\hyperref[\detokenize{language/core/basic: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.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
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}:

\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}

\sphinxAtStartPar
The term \sphinxcode{\sphinxupquote{(nosimpl t)}} simplifies to \sphinxcode{\sphinxupquote{t}} \sphinxstyleemphasis{except} in a definition.
More precisely, given:

\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}

\sphinxAtStartPar
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:}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{nosimpl}} trick only works if no reduction is apparent in
\sphinxcode{\sphinxupquote{t}}; in particular, the declaration:

\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}

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
A standard example making this technique shine is the case of
arithmetic operations. We define for instance:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{addn} \PYG{o}{:=} \PYG{k}{nosimpl} \PYG{n}{plus}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.


\paragraph{Congruence}
\label{\detokenize{proof-engine/ssreflect-proof-language:congruence}}\label{\detokenize{proof-engine/ssreflect-proof-language:congruence-ssr}}
\sphinxAtStartPar
Because of the way matching interferes with parameters of type families,
the tactic:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply}\PYG{o}{:} \PYG{n}{my\PYGZus{}congr\PYGZus{}property}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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 (tactic)@\spxentry{congr}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.congr}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{congr~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic:
\begin{itemize}
\item {} 
\sphinxAtStartPar
checks that the goal is a Leibniz equality;

\item {} 
\sphinxAtStartPar
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;

\item {} 
\sphinxAtStartPar
generates the subgoals corresponding to pairwise equalities of the arguments present in the goal.

\end{itemize}

\sphinxAtStartPar
The goal can be a non dependent product \sphinxcode{\sphinxupquote{P \sphinxhyphen{}> 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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
    \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{n}{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{k+kn}{Abort}\PYG{o}{.}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{goal}
    \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{n}{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}

\sphinxAtStartPar
The optional {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} forces the number of arguments for which the
tactic should generate equality proof obligations.

\sphinxAtStartPar
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}

\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{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
The tactic \sphinxcode{\sphinxupquote{rewrite \sphinxhyphen{}/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}

\sphinxAtStartPar
Like most \DUrole{smallcaps}{SSReflect} arguments, {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} can contain wildcards.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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}{goals}
    \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{n}{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}{goal} \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}{goal} \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}

\end{fulllineitems}\end{savenotes}



\subsubsection{Contextual patterns}
\label{\detokenize{proof-engine/ssreflect-proof-language:contextual-patterns}}\label{\detokenize{proof-engine/ssreflect-proof-language:contextual-patterns-ssr}}
\sphinxAtStartPar
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\sphinxhyphen{}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{proof-engine/vernacular-commands: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.

\sphinxAtStartPar
Contextual patterns mitigate these issues allowing to specify
occurrences according to the context they occur in.


\paragraph{Syntax}
\label{\detokenize{proof-engine/ssreflect-proof-language:syntax}}
\sphinxAtStartPar
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 
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
redex
&\sphinxstyletheadfamily 
\sphinxAtStartPar
subterms affected
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term}}
&
\sphinxAtStartPar
all occurrences of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ident in term}}
&
\sphinxAtStartPar
subterm of \sphinxcode{\sphinxupquote{term}} selected by \sphinxcode{\sphinxupquote{ident}}
&
\sphinxAtStartPar
all the subterms identified by \sphinxcode{\sphinxupquote{ident}} in all the
occurrences of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term1 in ident in term2}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term1}} in all s.m.r.
&
\sphinxAtStartPar
in all the subterms identified by
\sphinxcode{\sphinxupquote{ident}} in all the occurrences of \sphinxcode{\sphinxupquote{term2}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term1 as ident in term2}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term 1}}
&
\sphinxAtStartPar
in all the subterms identified by \sphinxcode{\sphinxupquote{ident}}
in all the occurrences of \sphinxcode{\sphinxupquote{term2{[}term 1 /ident{]}}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\sphinxAtStartPar
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 
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_pattern}}}}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
redex
&\sphinxstyletheadfamily 
\sphinxAtStartPar
subterms affected
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{in term}}
&
\sphinxAtStartPar
inferred from rule
&
\sphinxAtStartPar
in all s.m.r. in all occurrences of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{in ident in term}}
&
\sphinxAtStartPar
inferred from rule
&
\sphinxAtStartPar
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}

\sphinxAtStartPar
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 {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}}s
presented in the tables above can contain
holes.

\sphinxAtStartPar
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

\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}

\sphinxAtStartPar
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).


\paragraph{Matching contextual patterns}
\label{\detokenize{proof-engine/ssreflect-proof-language:matching-contextual-patterns}}
\sphinxAtStartPar
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 
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
instantiation order and place for \sphinxcode{\sphinxupquote{term\_i}} and redex
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term}} is matched against the goal, redex is unified with
the instantiation of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ident in term}}
&
\sphinxAtStartPar
\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
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term1 in ident in term2}}
&
\sphinxAtStartPar
\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
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{term1 as ident in term2}}
&
\sphinxAtStartPar
\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}

\sphinxAtStartPar
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 
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_pattern}}}}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
instantiation order and place for \sphinxcode{\sphinxupquote{term\_i}} and redex
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{in ident in term}}
&
\sphinxAtStartPar
\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
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{in term}}
&
\sphinxAtStartPar
\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}


\paragraph{Examples}
\label{\detokenize{proof-engine/ssreflect-proof-language:examples}}

\subparagraph{Contextual pattern in set and the : tactical}
\label{\detokenize{proof-engine/ssreflect-proof-language:contextual-pattern-in-set-and-the-tactical}}
\sphinxAtStartPar
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}

\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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{a} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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}}.

\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}

\sphinxAtStartPar
Contextual patterns can also be used as arguments of the \sphinxcode{\sphinxupquote{:}} tactical.
For example:

\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}


\subparagraph{Contextual patterns in rewrite}
\label{\detokenize{proof-engine/ssreflect-proof-language:contextual-patterns-in-rewrite}}
\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{0}} into \sphinxcode{\sphinxupquote{0 + 0}}.

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}

\sphinxAtStartPar
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}}.

\sphinxAtStartPar
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:

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}

\sphinxAtStartPar
The following tactic is quite tricky:

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}

\sphinxAtStartPar
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}}.

\sphinxAtStartPar
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.

\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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}


\paragraph{Patterns for recurrent contexts}
\label{\detokenize{proof-engine/ssreflect-proof-language:patterns-for-recurrent-contexts}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
The following example is taken from \sphinxcode{\sphinxupquote{ssreflect.v}} where the
\sphinxcode{\sphinxupquote{LHS}} and \sphinxcode{\sphinxupquote{RHS}} shortcuts are defined.

\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}

\sphinxAtStartPar
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:

\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}


\subsubsection{Views and reflection}
\label{\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection}}\label{\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
\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.


\paragraph{Interpreting eliminations}
\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-eliminations}}\label{\detokenize{proof-engine/ssreflect-proof-language:custom-elim-ssr}}
\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{V}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
is a synonym for:

\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}

\sphinxAtStartPar
where top is a fresh name and V any second\sphinxhyphen{}order lemma.

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
is a synonym for:

\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}

\sphinxAtStartPar
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 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).

\sphinxAtStartPar
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}

\sphinxAtStartPar
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}

\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{n}{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{n}{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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
One can define an alternative, reversed, induction principle on
inductively defined lists, by proving the following lemma:

\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{n}{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{n}{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}

\sphinxAtStartPar
Then the combination of elimination views with equation names result
in a concise syntax for reasoning inductively using the user\sphinxhyphen{}defined
elimination scheme.

\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{n}{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}{goal}
      
      \PYG{n}{d} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{d}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{[|} \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}{goals}
      
      \PYG{n}{d} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{d}
      \PYG{n}{u} \PYG{o}{:} \PYG{n}{list} \PYG{n}{d}
      \PYG{n}{v} \PYG{o}{:} \PYG{n}{d}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{nil} \PYG{o}{=} \PYG{n}{nil}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
User\sphinxhyphen{}provided eliminators (potentially generated with 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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{foo\PYGZus{}ind} \PYG{o}{:} \PYG{k}{forall} \PYG{n+nb+bp}{…}\PYG{o}{,} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{,} \PYG{n}{P} \PYG{n}{p1} \PYG{n+nb+bp}{…} \PYG{n}{pm}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
and consider the tactic:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{foo\PYGZus{}ind}\PYG{o}{:} \PYG{n}{e1} \PYG{n+nb+bp}{…} \PYG{o}{/} \PYG{n}{en}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{elim/}} tactic distinguishes two cases:
\begin{quote}\begin{description}
\item[{truncated eliminator}] \leavevmode
\sphinxAtStartPar
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 subterm 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
\sphinxAtStartPar
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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
Here is an example of a regular, but nontrivial, eliminator.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Here is a toy example illustrating this feature.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Function} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{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}{guarded} \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{}rect} \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}{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{n}{nat}\PYG{o}{]} \PYG{o}{[}\PYG{n}{P} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{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{n}{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}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
               \PYG{o}{|} \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{n}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{m} \PYG{n}{n}\PYG{o}{)}
    
    \PYG{n}{plus\PYGZus{}ind} \PYG{k}{is} \PYG{n}{not} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{k+kn}{Arguments} \PYG{n}{plus\PYGZus{}ind} \PYG{o}{[}\PYG{n}{m}\PYG{o}{]}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope} \PYG{o}{[}\PYG{n}{P}\PYG{o}{]}\PYG{o}{\PYGZpc{}}\PYG{n}{function\PYGZus{}scope} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{function\PYGZus{}scope}
      \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}
    \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}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
The following tactics are all valid and perform the same elimination
on this goal.

\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}

\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}{goals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{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{n}{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}{goal} \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{n}{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}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
     \PYG{o}{|} \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}

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k}{elim}\PYG{o}{/}\PYG{n}{plus\PYGZus{}ind}\PYG{o}{:} \PYG{n}{y} \PYG{o}{/} \PYG{o}{\PYGZus{}}\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}{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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
Here is an example of a truncated eliminator:

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Consider the goal:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{p} \PYG{n}{n} \PYG{o}{(}\PYG{n}{n\PYGZus{}gt0} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pr\PYGZus{}p} \PYG{o}{:} \PYG{n}{prime} \PYG{n}{p}\PYG{o}{)} \PYG{o}{:}
  \PYG{n}{p} \PYG{o}{\PYGZpc{}|} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{prod\PYGZus{}}\PYG{o}{(}\PYG{n}{i} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{prime\PYGZus{}decomp} \PYG{n}{n} \PYG{o}{|} \PYG{n}{i} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{k}{in} \PYG{n}{prime\PYGZus{}decomp} \PYG{n}{n}\PYG{o}{)} \PYG{n}{i}\PYG{o}{.}\PYG{l+m+mi}{1} \PYG{o}{\PYGZca{}} \PYG{n}{i}\PYG{o}{.}\PYG{l+m+mi}{2} \PYG{o}{\PYGZhy{}\PYGZgt{}}
    \PYG{k}{exists2} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{*} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{k}{in} \PYG{n}{prime\PYGZus{}decomp} \PYG{n}{n} \PYG{o}{\PYGZam{}} \PYG{n}{p} \PYG{o}{=} \PYG{n}{x}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{big\PYGZus{}prop}\PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{o}{[|} \PYG{n}{u} \PYG{n}{v} \PYG{n}{IHu} \PYG{n}{IHv} \PYG{o}{|} \PYG{o}{[}\PYG{n}{q} \PYG{n}{e}\PYG{o}{]} \PYG{o}{/=}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
where the type of the \sphinxcode{\sphinxupquote{big\_prop}} eliminator is

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{big\PYGZus{}prop}\PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{R} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Pb} \PYG{o}{:} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{idx} \PYG{o}{:} \PYG{n}{R}\PYG{o}{)} \PYG{o}{(}\PYG{n}{op1} \PYG{o}{:} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R}\PYG{o}{)}\PYG{o}{,} \PYG{n}{Pb} \PYG{n}{idx} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{R}\PYG{o}{,} \PYG{n}{Pb} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pb} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pb} \PYG{o}{(}\PYG{n}{op1} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{k}{forall} \PYG{o}{(}\PYG{n}{I} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{r} \PYG{o}{:} \PYG{n}{seq} \PYG{n}{I}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{pred} \PYG{n}{I}\PYG{o}{)} \PYG{o}{(}\PYG{n}{F} \PYG{o}{:} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R}\PYG{o}{)}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{i} \PYG{o}{:} \PYG{n}{I}\PYG{o}{,} \PYG{n}{P} \PYG{n}{i} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pb} \PYG{o}{(}\PYG{n}{F} \PYG{n}{i}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
    \PYG{n}{Pb} \PYG{o}{(}\PYG{n+nb+bp}{\PYGZbs{}}\PYG{n}{big}\PYG{o}{[}\PYG{n}{op1}\PYG{o}{/}\PYG{n}{idx}\PYG{o}{]}\PYG{o}{\PYGZus{}}\PYG{o}{(}\PYG{n}{i} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{r} \PYG{o}{|} \PYG{n}{P} \PYG{n}{i}\PYG{o}{)} \PYG{n}{F} \PYG{n}{i}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Since the pattern for the argument of Pb is not specified, the
inferred one is used instead: \sphinxcode{\sphinxupquote{big{[}\_/\_{]}\_(i <\sphinxhyphen{} \_ | \_ i) \_ i}},
and after the introductions, the following goals are generated:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{subgoal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
  \PYG{n}{p} \PYG{o}{\PYGZpc{}|} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{exists2} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{*} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{k}{in} \PYG{n}{prime\PYGZus{}decomp} \PYG{n}{n} \PYG{o}{\PYGZam{}} \PYG{n}{p} \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}{p} \PYG{o}{\PYGZpc{}|} \PYG{n}{u} \PYG{o}{*} \PYG{n}{v} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{exists2} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{*} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{k}{in} \PYG{n}{prime\PYGZus{}decomp} \PYG{n}{n} \PYG{o}{\PYGZam{}} \PYG{n}{p} \PYG{o}{=} \PYG{n}{x}\PYG{o}{.}\PYG{l+m+mi}{1}
\PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
  \PYG{o}{(}\PYG{n}{q}\PYG{o}{,} \PYG{n}{e}\PYG{o}{)} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{k}{in} \PYG{n}{prime\PYGZus{}decomp} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{p} \PYG{o}{\PYGZpc{}|} \PYG{n}{q} \PYG{o}{\PYGZca{}} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}}
    \PYG{k}{exists2} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{*} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{n+nb+bp}{\PYGZbs{}}\PYG{k}{in} \PYG{n}{prime\PYGZus{}decomp} \PYG{n}{n} \PYG{o}{\PYGZam{}} \PYG{n}{p} \PYG{o}{=} \PYG{n}{x}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that the pattern matching algorithm instantiated all the
variables occurring in the pattern.
\end{sphinxadmonition}


\paragraph{Interpreting assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-assumptions}}\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-assumptions-ssr}}
\sphinxAtStartPar
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}}}}), 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 : \_ => \_}} switches, like in the
following example, where \sphinxcode{\sphinxupquote{||}} is a notation for the boolean
disjunction.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{P} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{|}\PYG{o}{|} \PYG{n}{a}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{goal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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:

\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}{goal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
or more directly:

\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}{goal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{|}\PYG{o}{|} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \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{n}{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}{|}\PYG{o}{|} \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}{|} \PYG{n}{HPb}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \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{n}{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
\end{sphinxVerbatim}

\sphinxAtStartPar
This view tactic performs:

\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}{|} \PYG{n}{HPb}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{|}\PYG{o}{|} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \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{n}{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}{|}\PYG{o}{|} \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}{goal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \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{n}{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}

\sphinxAtStartPar
has the same behavior as the first example above.

\sphinxAtStartPar
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:

\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}{|}\PYG{o}{|} \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}

\sphinxAtStartPar
where:

\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}


\subparagraph{Specializing assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:specializing-assumptions}}
\sphinxAtStartPar
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\sphinxhyphen{}order
assumption to some given arguments.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{n}{z} \PYG{o}{:} \PYG{n}{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{n}{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}{goal}
      
      \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}


\paragraph{Interpreting goals}
\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-goals}}
\sphinxAtStartPar
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}

\sphinxAtStartPar
The following example use the \sphinxcode{\sphinxupquote{\textasciitilde{}\textasciitilde{}}} prenex notation for boolean negation:
\end{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{|}\PYG{o}{|} \PYG{n}{a}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{goal}
    \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{n}{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{n}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
thus in this case, the tactic \sphinxcode{\sphinxupquote{apply/PQequiv}} is equivalent to
\sphinxcode{\sphinxupquote{apply: (iffRL (PQequiv \_ \_))}}, where \sphinxcode{\sphinxupquote{iffRL}} is the analogue of
\sphinxcode{\sphinxupquote{iffRL}} for the converse implication.
\end{sphinxadmonition}

\sphinxAtStartPar
Any \DUrole{smallcaps}{SSReflect} term whose type coerces to a double implication can be
used as a view for goal interpretation.

\sphinxAtStartPar
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:}
\sphinxAtStartPar
Goal interpretation view tactics are \sphinxstyleemphasis{not} compatible with
the bookkeeping tactical \sphinxcode{\sphinxupquote{=>}} since this would be redundant with the
\sphinxcode{\sphinxupquote{apply: term => \_}} construction.
\end{sphinxadmonition}


\paragraph{Boolean reflection}
\label{\detokenize{proof-engine/ssreflect-proof-language:boolean-reflection}}
\sphinxAtStartPar
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 Coq
tactics.  For example, 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 => G}} to two
subgoals \sphinxcode{\sphinxupquote{A => G}} and \sphinxcode{\sphinxupquote{B => G}}.

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{orb} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Properties of such connectives are also established using case
analysis

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{b} \PYG{o}{:} \PYG{n}{b} \PYG{o}{|}\PYG{o}{|} \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}{goal}
      
      \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}

\sphinxAtStartPar
Thus, \sphinxcode{\sphinxupquote{Prop}} and \sphinxcode{\sphinxupquote{bool}} are truly complementary: the former supports
robust natural deduction, the latter allows brute\sphinxhyphen{}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.

\sphinxAtStartPar
First, booleans are injected into propositions using the coercion
mechanism:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Coercion} \PYG{n}{is\PYGZus{}true} \PYG{o}{(}\PYG{n}{b} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{b} \PYG{o}{=} \PYG{n+nb+bp}{true}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This allows any boolean formula \sphinxcode{\sphinxupquote{b}} to be used in a context where Coq
would expect a proposition, e.g., after \sphinxcode{\sphinxupquote{Lemma … :}}. It is then
interpreted as \sphinxcode{\sphinxupquote{(is\_true b)}}, i.e., the proposition \sphinxcode{\sphinxupquote{b = true}}. Coercions
are elided by the pretty\sphinxhyphen{}printer, so they are essentially transparent
to the user.


\paragraph{The reflect predicate}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-reflect-predicate}}
\sphinxAtStartPar
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:

\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{n}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{|} \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}{|} \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}

\sphinxAtStartPar
The statement \sphinxcode{\sphinxupquote{(reflect P b)}} asserts that \sphinxcode{\sphinxupquote{(is\_true b)}} and \sphinxcode{\sphinxupquote{P}} are
logically equivalent propositions.

\sphinxAtStartPar
For instance, the following lemma:

\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}

\sphinxAtStartPar
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}}.

\sphinxAtStartPar
Expressing logical equivalences through this family of inductive types
makes possible to take benefit from \sphinxstyleemphasis{rewritable equations} associated
to the case analysis of Coq’s inductive types.

\sphinxAtStartPar
Since the equivalence predicate is defined in Coq as:

\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}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{/\textbackslash{}}} is a notation for \sphinxcode{\sphinxupquote{and}}:

\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}

\sphinxAtStartPar
This make case analysis very different according to the way an
equivalence property has been defined.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{andE} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Let us compare the respective behaviors of \sphinxcode{\sphinxupquote{andE}} and \sphinxcode{\sphinxupquote{andP}}.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|}\PYG{n}{b2}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \PYG{n}{b2}\PYG{o}{)}
\end{sphinxVerbatim}

\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}{goal}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \PYG{n}{b2}\PYG{o}{)}
\end{sphinxVerbatim}

\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}{goals}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2} \PYG{o}{:} \PYG{n}{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}{goal} \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}{|}\PYG{o}{|} \PYG{n}{b2}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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{||}} and \sphinxcode{\sphinxupquote{\textbackslash{}/}},
\sphinxcode{\sphinxupquote{negP}} relates \sphinxcode{\sphinxupquote{\textasciitilde{}\textasciitilde{}}} and \sphinxcode{\sphinxupquote{\textasciitilde{}}}.

\sphinxAtStartPar
The view mechanism is compatible with reflect predicates.

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
    \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{n}{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}

\sphinxAtStartPar
Conversely

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
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.


\paragraph{General mechanism for interpreting goals and assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:general-mechanism-for-interpreting-goals-and-assumptions}}

\subparagraph{Specializing assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:id15}}
\sphinxAtStartPar
The \DUrole{smallcaps}{SSReflect} tactic:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{/}\PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{n}{term1} \PYG{n+nb+bp}{…} \PYG{n}{termn}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
is equivalent to the tactic:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intro} \PYG{n}{top}\PYG{o}{;} \PYG{k}{generalize} \PYG{o}{(}\PYG{n}{top} \PYG{n}{term1} \PYG{n+nb+bp}{…} \PYG{n}{termn}\PYG{o}{)}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{top}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{top}} is a fresh name for introducing the top assumption of the
current goal.


\subparagraph{Interpreting assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:id16}}
\sphinxAtStartPar
The general form of an assumption view tactic is:


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{move}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{case}}~/~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
The term , called the \sphinxstyleemphasis{view lemma} can be:
\begin{itemize}
\item {} 
\sphinxAtStartPar
a (term coercible to a) function;

\item {} 
\sphinxAtStartPar
a (possibly quantified) implication;

\item {} 
\sphinxAtStartPar
a (possibly quantified) double implication;

\item {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
Let \sphinxcode{\sphinxupquote{top}} be the top assumption in the goal.

\sphinxAtStartPar
There are three steps in the behavior of an assumption view tactic:
\begin{itemize}
\item {} 
\sphinxAtStartPar
It first introduces \sphinxcode{\sphinxupquote{top}}.

\item {} 
\sphinxAtStartPar
If the type of {\hyperref[\detokenize{language/core/basic: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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
It finally clears top.

\end{itemize}

\sphinxAtStartPar
For a \sphinxcode{\sphinxupquote{case/term}} tactic, the generalisation step is replaced by a
case analysis step.

\sphinxAtStartPar
\sphinxstyleemphasis{View hints} are declared by the user (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Views and reflection}}}}) 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.

\sphinxAtStartPar
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}}:

\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}

\sphinxAtStartPar
which transforms a double implication into the left\sphinxhyphen{}to\sphinxhyphen{}right one, or:

\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}

\sphinxAtStartPar
which produces the converse implication. In both cases, the two
first Prop arguments are implicit.

\sphinxAtStartPar
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{reflect}} predicate, which are by
default the ones present in the file \sphinxcode{\sphinxupquote{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{introN}\PYG{o}{.}
    \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{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
    \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{n}{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}

\sphinxAtStartPar
In fact this last script does not
exactly use the hint \sphinxcode{\sphinxupquote{introN}}, but the more general hint:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{introNTF}\PYG{o}{.}
    \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{n}{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}
\end{sphinxVerbatim}

\sphinxAtStartPar
The lemma \sphinxcode{\sphinxupquote{introN}} is an instantiation of \sphinxcode{\sphinxupquote{introNF}} using \sphinxcode{\sphinxupquote{c := true}}.
\end{sphinxadmonition}

\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}

\sphinxAtStartPar
Interpreting goals

\sphinxAtStartPar
A goal interpretation view tactic of the form:


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply/{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
applied to a goal \sphinxcode{\sphinxupquote{top}} is interpreted in the following way:
\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
Like assumption interpretation view hints, goal interpretation ones
are user\sphinxhyphen{}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.


\paragraph{Interpreting equivalences}
\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-equivalences}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
The syntax of double views is:


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply/{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}/{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
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.

\sphinxAtStartPar
In this context, the identity view can be used when no view has to be applied:

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{n}{b3} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{=} \PYG{n}{b3}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2}\PYG{o}{,} \PYG{n}{b3} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{goals}
    \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{n}{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}{|}\PYG{o}{|} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b3}
    
    \PYG{n}{goal} \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}{|}\PYG{o}{|} \PYG{n}{b2}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
The same goal can be decomposed in several ways, and the user may
choose the most convenient interpretation.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{n}{b3} \PYG{o}{:} \PYG{n}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{|}\PYG{o}{|} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{=} \PYG{n}{b3}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2}\PYG{o}{,} \PYG{n}{b3} \PYG{o}{:} \PYG{n}{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}{|}\PYG{o}{|} \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}{goals}
    \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{n}{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}{goal} \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}


\paragraph{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}}\index{Hint View for move (command)@\spxentry{Hint View for move}\spxextra{command}}\index{Hint View for apply (command)@\spxentry{Hint View for apply}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{|~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{|~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This command can be used to extend the database of hints for the view
mechanism.

\sphinxAtStartPar
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.

\sphinxAtStartPar
The {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the name of the lemma to be
declared as a hint. If \sphinxcode{\sphinxupquote{move}} is used as
tactic, the hint is declared for assumption interpretation tactics,
\sphinxcode{\sphinxupquote{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.


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~View~for~apply//{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{|~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This variant with a double slash \sphinxcode{\sphinxupquote{//}}, declares hint views for right
hand sides of double views.

\sphinxAtStartPar
See the files \sphinxcode{\sphinxupquote{ssreflect.v}} and \sphinxcode{\sphinxupquote{ssrbool.v}} for examples.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Multiple views}
\label{\detokenize{proof-engine/ssreflect-proof-language:multiple-views}}
\sphinxAtStartPar
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

\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}

\sphinxAtStartPar
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}}.

\sphinxAtStartPar
Note that the NO\sphinxhyphen{}OP intro pattern \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} can be used to separate two views,
making the two following examples equivalent:

\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}

\sphinxAtStartPar
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}

\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}{goal}
      
      \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}{goal}
      
      \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}

\sphinxAtStartPar
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.


\subsubsection{SSReflect searching tool}
\label{\detokenize{proof-engine/ssreflect-proof-language:ssr-searching-tool}}\index{Search (ssreflect) (command)@\spxentry{Search (ssreflect)}\spxextra{command}}

\begin{savenotes}\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/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}}~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/variants:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\%~{\hyperref[\detokenize{language/core/basic: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}{\sphinxhyphen{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}~
\sphinxAtStartPar
\DUrole{versionmodified,changed}{Changed in version 8.12: }This command is only available when loading a separate plugin
(\sphinxcode{\sphinxupquote{ssrsearch}}).

\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.12: }This command is deprecated since all the additional features it
provides have been integrated in the standard {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}}
command.

\sphinxAtStartPar
This is the \DUrole{smallcaps}{SSReflect} extension of the Search command. {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is the
name of an open module. This command returns the list of lemmas:
\begin{itemize}
\item {} 
\sphinxAtStartPar
whose \sphinxstyleemphasis{conclusion} contains a subterm matching the optional first
pattern. A \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} reverses the test, producing the list of lemmas whose
conclusion does not contain any subterm matching the pattern;

\item {} 
\sphinxAtStartPar
whose name contains the given string. A \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} 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.,
\sphinxcode{\sphinxupquote{\DUrole{operator}{+}}} for \sphinxcode{\sphinxupquote{\DUrole{name}{addn}}}), if this is unambiguous; otherwise the diagnostic
includes the output of the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Locate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Locate}}}}} command.

\item {} 
\sphinxAtStartPar
whose statement, including assumptions and types, contains a subterm
matching the next patterns. If a pattern is prefixed by \sphinxcode{\sphinxupquote{\sphinxhyphen{}}}, the test is
reversed;

\item {} 
\sphinxAtStartPar
contained in the given list of modules, except the ones in the
modules prefixed by a \sphinxcode{\sphinxupquote{\sphinxhyphen{}}}.

\end{itemize}

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
Patterns with holes should be surrounded by parentheses.

\item {} 
\sphinxAtStartPar
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{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ssrsearch}\PYG{o}{.}
\end{sphinxVerbatim}

\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{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}{SSReflect\PYGZsq{}s} \PYG{k+kn}{Search} \PYG{n}{command} \PYG{k}{is} \PYG{n}{deprecated}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{deprecated}\PYG{o}{\PYGZhy{}}\PYG{n}{ssr}\PYG{o}{\PYGZhy{}}\PYG{n}{search}\PYG{o}{,}\PYG{n}{deprecated}\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{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZti{}\PYGZti{} \PYGZus{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}
    \PYG{n}{In} \PYG{n}{bool\PYGZus{}scope}\PYG{o}{,} \PYG{o}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZti{}\PYGZti{} b}\PYG{l+s+s2}{\PYGZdq{}}\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{o}{:} \PYG{k}{forall} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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{o}{:} \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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{o}{:} \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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{o}{:} \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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{o}{:} \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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{o}{:} \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{n}{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}{contra\PYGZus{}notN}\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{n}{bool}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b}
    
    \PYG{n}{contraPN}\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{n}{bool}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{P}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b}
    
    \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{n}{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}

\item {} 
\sphinxAtStartPar
A diagnostic is issued if there are different matching notations; it
is an error if all matches are partial.

\item {} 
\sphinxAtStartPar
Similarly, a diagnostic warns about multiple interpretations, and
signals an error if there is no default one.

\item {} 
\sphinxAtStartPar
The command \sphinxcode{\sphinxupquote{Search in M.}} is a way of obtaining the complete
signature of the module \sphinxcode{\sphinxupquote{M}}.

\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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}
\end{sphinxadmonition}


\subsubsection{Synopsis and Index}
\label{\detokenize{proof-engine/ssreflect-proof-language:synopsis-and-index}}

\paragraph{Parameters}
\label{\detokenize{proof-engine/ssreflect-proof-language:parameters}}
\sphinxAtStartPar
\DUrole{smallcaps}{SSReflect} tactics
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_tactic}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_tactic}]{\sphinxcrossref{\DUrole{hole}{d\_tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{elim}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{case}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{congr}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{apply}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{exact}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{move}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Notation scope
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-key}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-key}]{\sphinxcrossref{\DUrole{hole}{key}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Module name
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-modname}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-modname}]{\sphinxcrossref{\DUrole{hole}{modname}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Natural number
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-nat_or_ident}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-nat_or_ident}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_ident}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
where {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is an Ltac variable denoting a standard Coq number
(should not be the name of a tactic which can be followed by a
bracket \sphinxcode{\sphinxupquote{{[}}}, like \sphinxcode{\sphinxupquote{do}}, \sphinxcode{\sphinxupquote{have}},…)


\paragraph{Items and switches}
\label{\detokenize{proof-engine/ssreflect-proof-language:items-and-switches}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}]{\sphinxcrossref{\DUrole{hole}{ssr\_binder}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{( {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}} )}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
binder see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{curlies}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} \}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
clear switch see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
context pattern see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:contextual-patterns-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Contextual patterns}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\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{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{( {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}} )}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
discharge item see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}]{\sphinxcrossref{\DUrole{hole}{gen\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{( {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} )}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}} )}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
generalization item see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\_}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{?}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{*}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{+}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\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{alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{?}\DUrole{notation-sub}{|}} {]}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\sphinxhyphen{}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[}: \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} {]}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
intro pattern {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\DUrole{hole}{i\_view}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_block}]{\sphinxcrossref{\DUrole{hole}{i\_block}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
view {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_view}]{\sphinxcrossref{\DUrole{hole}{i\_view}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\{\}}\DUrole{notation-sup}{?}} \DUrole{alternative}{\DUrole{alternative-block}{/{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{/ltac:( {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} )}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
intro block {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_block}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_block}]{\sphinxcrossref{\DUrole{hole}{i\_block}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{[}\textasciicircum{} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[}\textasciicircum{}\textasciitilde{} \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}} {]}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
intro item  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-int_mult}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-int_mult}]{\sphinxcrossref{\DUrole{hole}{int\_mult}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult_mark}]{\sphinxcrossref{\DUrole{hole}{mult\_mark}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
multiplier  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{curlies}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{+}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\sphinxhyphen{}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{*}} \}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
occur. switch see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:occurrence-selection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Occurrence selection}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\DUrole{hole}{mult}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult_mark}]{\sphinxcrossref{\DUrole{hole}{mult\_mark}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
multiplier see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult_mark}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult_mark}]{\sphinxcrossref{\DUrole{hole}{mult\_mark}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{?}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{!}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
multiplier mark see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\DUrole{hole}{r\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{\DUrole{repeat-wrapper}{\DUrole{repeat}{/}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
rewrite item see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}]{\sphinxcrossref{\DUrole{hole}{r\_prefix}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\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}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\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}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
rewrite prefix see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\DUrole{hole}{r\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
rewrite pattern see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_step}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_step}]{\sphinxcrossref{\DUrole{hole}{r\_step}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\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}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
rewrite step see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{/=}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{//}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{//=}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
simplify switch see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}


\paragraph{Tactics}
\label{\detokenize{proof-engine/ssreflect-proof-language:tactics}}
\sphinxAtStartPar
\sphinxstyleemphasis{Note}: \sphinxcode{\sphinxupquote{without loss}} and \sphinxcode{\sphinxupquote{suffices}} are synonyms for \sphinxcode{\sphinxupquote{wlog}} and \sphinxcode{\sphinxupquote{suff}}
respectively.
\index{move (ssreflect) (tactic)@\spxentry{move (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id29}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move}}}}
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}} (see  {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Bookkeeping}}}})

\end{fulllineitems}\end{savenotes}

\index{apply (ssreflect) (tactic)@\spxentry{apply (ssreflect)}\spxextra{tactic}}\index{exact (ssreflect) (tactic)@\spxentry{exact (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id30}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply}}}}\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.exact-(ssreflect)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exact}}}}
\sphinxAtStartPar
application (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The defective tactics}}}})

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{abstract:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim}}}}
\sphinxAtStartPar
induction (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The defective tactics}}}})

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{case}}}}
\sphinxAtStartPar
case analysis (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The defective tactics}}}})

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \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}{+}}}}}}
\sphinxAtStartPar
rewrite (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}})

\end{fulllineitems}\end{savenotes}

\index{under (tactic)@\spxentry{under}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id31}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{under~\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\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{repeat-wrapper}{\DUrole{repeat}{do~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[}~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}}~{]}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
under (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:under-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting under binders}}}})

\end{fulllineitems}\end{savenotes}

\index{over (tactic)@\spxentry{over}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id32}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{over}}}}
\sphinxAtStartPar
over (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:over-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The over tactic}}}})

\end{fulllineitems}\end{savenotes}

\index{generally have (tactic)@\spxentry{generally have}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id33}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{gen~have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.generally-have}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generally~have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
forward chaining (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}})

\end{fulllineitems}\end{savenotes}

\index{wlog (tactic)@\spxentry{wlog}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id34}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}]{\sphinxcrossref{\DUrole{hole}{gen\_item}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}}}\DUrole{notation-sup}{*}}~/~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
specializing (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}})

\end{fulllineitems}\end{savenotes}

\index{suff (tactic)@\spxentry{suff}\spxextra{tactic}}\index{suffices (tactic)@\spxentry{suffices}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.suff}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.suffices}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id35}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
backchaining (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}})

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
local definition (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:definitions-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Definitions}}}})

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~{\hyperref[\detokenize{language/core/basic: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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
local function definition

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~fix~{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_decl}]{\sphinxcrossref{\DUrole{hole}{fix\_decl}}}}}}}}
\sphinxAtStartPar
local fix definition

\end{fulllineitems}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~cofix~{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_decl}]{\sphinxcrossref{\DUrole{hole}{fix\_decl}}}}}}}}
\sphinxAtStartPar
local cofix definition

\end{fulllineitems}\end{savenotes}

\index{set (ssreflect) (tactic)@\spxentry{set (ssreflect)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id36}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/core/basic: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{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{(~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}})}}}}}}
\sphinxAtStartPar
abbreviation (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}})

\end{fulllineitems}\end{savenotes}

\index{unlock (tactic)@\spxentry{unlock}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id37}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
unlock (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:locking-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Locking, unlocking}}}})

\end{fulllineitems}\end{savenotes}

\index{congr (tactic)@\spxentry{congr}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id38}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{congr~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
congruence (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:congruence-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Congruence}}}})

\end{fulllineitems}\end{savenotes}



\paragraph{Tacticals}
\label{\detokenize{proof-engine/ssreflect-proof-language:tacticals}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-tactic}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\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/core/basic: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}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
discharge {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-tactic}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} => \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{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
introduction see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-tactic}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} in \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}]{\sphinxcrossref{\DUrole{hole}{gen\_item}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\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}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
localization see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:localization-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Localization}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-tactic}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\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{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} {]}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
iteration  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-tactic}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} ; \DUrole{alternative}{\DUrole{alternative-block}{first}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{last}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}} \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} {]}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
selector  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Selectors}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-tactic}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} ; \DUrole{alternative}{\DUrole{alternative-block}{first}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{last}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
rotation see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Selectors}}}}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-tactic}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{by \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}} {]}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
closing see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:terminators-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Terminators}}}}


\paragraph{Commands}
\label{\detokenize{proof-engine/ssreflect-proof-language:commands}}\index{Hint View for (command)@\spxentry{Hint View for}\spxextra{command}}

\begin{savenotes}\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{alternative}{\DUrole{alternative-block}{move}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{apply}}~/~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{|~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
view hint declaration (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:declaring-new-hints-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Declaring new Hint Views}}}})

\end{fulllineitems}\end{savenotes}

\index{Hint View for apply (command)@\spxentry{Hint View for apply}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id39}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~View~for~apply~//~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
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}}}})

\end{fulllineitems}\end{savenotes}

\index{Prenex Implicits (command)@\spxentry{Prenex Implicits}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:id40}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Prenex~Implicits~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
prenex implicits declaration (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:parametric-polymorphism-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Parametric polymorphism}}}})

\end{fulllineitems}\end{savenotes}



\paragraph{Settings}
\label{\detokenize{proof-engine/ssreflect-proof-language:settings}}\index{Debug Ssreflect (flag)@\spxentry{Debug Ssreflect}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:flag.Debug-Ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~Ssreflect}}}}
\sphinxAtStartPar
\sphinxstyleemphasis{Developer only.} Print debug information on reflect.

\end{fulllineitems}\end{savenotes}

\index{Debug SsrMatching (flag)@\spxentry{Debug SsrMatching}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:flag.Debug-SsrMatching}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~SsrMatching}}}}
\sphinxAtStartPar
\sphinxstyleemphasis{Developer only.} Print debug information on SSR matching.

\end{fulllineitems}\end{savenotes}



\section{Automatic solvers and programmable tactics}
\label{\detokenize{proofs/automatic-tactics/index:automatic-solvers-and-programmable-tactics}}\label{\detokenize{proofs/automatic-tactics/index:automatic-tactics}}\label{\detokenize{proofs/automatic-tactics/index::doc}}
\sphinxAtStartPar
Some tactics are largely automated and are able to solve complex
goals.  This chapter presents both built\sphinxhyphen{}in solvers that can
be used on specific categories of goals and
programmable tactics that the user can instrument to handle
complex goals in new domains.


\subsection{Solvers for logic and equality}
\label{\detokenize{proofs/automatic-tactics/logic:solvers-for-logic-and-equality}}\label{\detokenize{proofs/automatic-tactics/logic:decisionprocedures}}\label{\detokenize{proofs/automatic-tactics/logic::doc}}\index{tauto (tactic)@\spxentry{tauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{tauto}}}}
\sphinxAtStartPar
This tactic implements a decision procedure for intuitionistic propositional
calculus based on the contraction\sphinxhyphen{}free sequent calculi LJT* of Roy Dyckhoff
{[}\hyperlink{cite.zebibliography:id19}{Dyc92}{]}. Note that {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} succeeds on any instance of an
intuitionistic tautological proposition. {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} unfolds negations and
logical equivalence but does not unfold any other definition.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The following goal can be proved by {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} whereas {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} would
fail:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{P} \PYG{o}{:} \PYG{n}{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}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Moreover, if it has nothing else to do, {\hyperref[\detokenize{proofs/automatic-tactics/logic: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{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} can for instance for:

\begin{sphinxadmonition}{note}{Example}

\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{n}{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{n}{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{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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{n}{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{n}{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}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
In contrast, {\hyperref[\detokenize{proofs/automatic-tactics/logic: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{name}{nat} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{keyword,type}{Prop}\DUrole{operator}{),} \DUrole{name}{A} \DUrole{operator}{\textbackslash{}/} \DUrole{operator}{(}\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{nat}\DUrole{operator}{,} \DUrole{operator}{\textasciitilde{}} \DUrole{name}{A} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{P} \DUrole{name}{x}\DUrole{operator}{)} \DUrole{operator}{\sphinxhyphen{}>}}}
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{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{name}{nat}\DUrole{operator}{,} \DUrole{operator}{\textasciitilde{}} \DUrole{name}{A} \DUrole{operator}{\sphinxhyphen{}>} \DUrole{name}{P} \DUrole{name}{x}\DUrole{operator}{)}}} cannot be treated as atomic and
an instantiation of \sphinxcode{\sphinxupquote{x}} is necessary.
\end{sphinxadmonition}
\index{dtauto (tactic)@\spxentry{dtauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:tacn.dtauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dtauto}}}}
\sphinxAtStartPar
While {\hyperref[\detokenize{proofs/automatic-tactics/logic: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}} and \sphinxcode{\sphinxupquote{True}}, {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.dtauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dtauto}}}}} also recognizes all inductive
types with one constructor and no indices, i.e. record\sphinxhyphen{}style connectives.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{intuition (tactic)@\spxentry{intuition}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:tacn.intuition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intuition~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Uses the search tree built by the decision procedure for {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}}
to generate a set of subgoals equivalent to the original one (but
simpler than it) and applies \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} to them {[}\hyperlink{cite.zebibliography:id38}{Mun94}{]}. If
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} is not specified, it defaults to \sphinxcode{\sphinxupquote{\DUrole{notation}{auto with *}}}
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} fails on some goals then {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}} fails. In fact,
{\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} is simply \sphinxcode{\sphinxupquote{\DUrole{keyword}{intuition} \DUrole{name}{fail}}}.

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/logic: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}} and \sphinxcode{\sphinxupquote{True}}.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For instance, the tactic \sphinxcode{\sphinxupquote{\DUrole{keyword}{intuition} \DUrole{keyword}{auto}}} applied to the goal:

\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}

\sphinxAtStartPar
internally replaces it by the equivalent one:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(forall (x:nat), P x), B |\PYGZhy{} P O
\end{sphinxVerbatim}

\sphinxAtStartPar
and then uses {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} which completes the proof.
\end{sphinxadmonition}
\index{dintuition (tactic)@\spxentry{dintuition}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:tacn.dintuition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dintuition~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
In addition to the inductively defined connectives recognized by {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}},
{\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.dintuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dintuition}}}}} also recognizes all inductive
types with one constructor and no indices, i.e. record\sphinxhyphen{}style connectives.

\end{fulllineitems}\end{savenotes}

\index{Intuition Negation Unfolding (flag)@\spxentry{Intuition Negation Unfolding}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:flag.Intuition-Negation-Unfolding}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Intuition~Negation~Unfolding}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls whether {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}} unfolds inner negations which do not need
to be unfolded. It is on by default.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{rtauto (tactic)@\spxentry{rtauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:tacn.rtauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rtauto}}}}
\sphinxAtStartPar
Solves propositional tautologies similarly to
{\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}}, but 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.

\sphinxAtStartPar
Users should be aware that this difference may result in faster proof search
but slower proof checking, and {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.rtauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rtauto}}}}} might not solve goals that
{\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} would be able to solve (e.g. goals involving universal
quantifiers).

\sphinxAtStartPar
Note that this tactic is only available after a \sphinxcode{\sphinxupquote{Require Import Rtauto}}.

\end{fulllineitems}\end{savenotes}

\index{firstorder (tactic)@\spxentry{firstorder}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:tacn.firstorder}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{firstorder~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
An experimental extension of {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} to
first\sphinxhyphen{}order reasoning. It is not restricted to
usual logical connectives but instead can reason about any first\sphinxhyphen{}order class
inductive definition.
\begin{description}
\item[{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}}] \leavevmode
\sphinxAtStartPar
Tries to solve the goal with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} when no logical rule applies.
If unspecified, the tactic uses the default from the {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:opt.Firstorder-Solver}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Firstorder Solver}}}}}
option.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{using \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}] \leavevmode
\sphinxAtStartPar
Adds the lemmas \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}} to the proof search environment. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
refers to an inductive type, its constructors are
added to the proof search environment.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{with \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}] \leavevmode
\sphinxAtStartPar
Adds lemmas from {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} hint bases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} to the proof search
environment.

\end{description}
\index{Firstorder Solver (option)@\spxentry{Firstorder Solver}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:opt.Firstorder-Solver}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Firstorder~Solver~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}
\sphinxAtStartPar
The default tactic used by {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.firstorder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{firstorder}}}}} when no rule applies in
\sphinxcode{\sphinxupquote{\DUrole{keyword}{auto} \DUrole{keyword}{with} \DUrole{name}{core}}}.  It can be set locally or globally using this {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}}.

\end{fulllineitems}\end{savenotes}

\index{Print Firstorder Solver (command)@\spxentry{Print Firstorder Solver}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:cmd.Print-Firstorder-Solver}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Firstorder~Solver}}}}
\sphinxAtStartPar
Prints the default tactic used by {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.firstorder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{firstorder}}}}} when no rule applies.

\end{fulllineitems}\end{savenotes}

\index{Firstorder Depth (option)@\spxentry{Firstorder Depth}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:opt.Firstorder-Depth}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Firstorder~Depth~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} controls the proof search depth bound.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{congruence (tactic)@\spxentry{congruence}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:tacn.congruence}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{congruence~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}~\begin{description}
\item[{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}}] \leavevmode
\sphinxAtStartPar
Specifies the maximum number of hypotheses stating quantified equalities that may be added
to the problem in order to solve it. The default is 1000.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{with \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Adds \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}}}} to the pool of terms used by {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}}. This helps
in case you have partially applied constructors in your goal.

\end{description}

\sphinxAtStartPar
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{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}}). If the goal
is a non\sphinxhyphen{}quantified equality, congruence tries to prove it with non\sphinxhyphen{}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.

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/logic: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.

\sphinxAtStartPar
Increasing the maximum number of hypotheses may solve
problems that would have failed with a smaller value.  It will make failures slower but it
won't make successes found with the smaller value any slower.
You may want to use {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert}}}}} to add some lemmas as
hypotheses so that {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}} can use them.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \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}{goal}
      
      \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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}

\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}{goal}
      
      \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}{goal}
      
      \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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{I don’t know how to handle dependent equality (error)@\spxentry{I don’t know how to handle dependent equality}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:exn.I-don_u2019t-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.}}}}
\sphinxAtStartPar
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\sphinxhyphen{}typed functions.

\end{fulllineitems}\end{savenotes}

\index{Goal is solvable by congruence but some arguments are missing. Try congruence with ‘term’…‘term’, replacing metavariables by arbitrary terms (error)@\spxentry{Goal is solvable by congruence but some arguments are missing. Try congruence with ‘term’…‘term’, replacing metavariables by arbitrary terms}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:exn.Goal-is-solvable-by-congruence-but-some-arguments-are-missing.-Try-congruence-with-_u2018term_u2019_u2026_u2018term_u2019,-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/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}},~replacing~metavariables~by~arbitrary~terms.}}}}
\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{with}} clause.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Debug}}}}} \sphinxcode{\sphinxupquote{"congruence"}} makes {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}} print debug information.

\end{fulllineitems}\end{savenotes}

\index{btauto (tactic)@\spxentry{btauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:tacn.btauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{btauto}}}}
\sphinxAtStartPar
The tactic {\hyperref[\detokenize{proofs/automatic-tactics/logic: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 \sphinxcode{\sphinxupquote{t}} and \sphinxcode{\sphinxupquote{u}} are
constructed over the following grammar:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{true}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{false}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{orb {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}} {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{andb {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}} {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{xorb {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}} {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{negb {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{if {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}} then {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}} else {\hyperref[\detokenize{proofs/automatic-tactics/logic:grammar-token-btauto_term}]{\sphinxcrossref{\DUrole{hole}{btauto\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Whenever the formula supplied is not a tautology, it also provides a
counter\sphinxhyphen{}example.

\sphinxAtStartPar
Internally, it uses a system very similar to the one of the ring
tactic.

\sphinxAtStartPar
Note that this tactic is only available after a \sphinxcode{\sphinxupquote{Require Import Btauto}}.
\index{Cannot recognize a boolean equality (error)@\spxentry{Cannot recognize a boolean equality}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/logic:coq:exn.Cannot-recognize-a-boolean-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~recognize~a~boolean~equality.}}}}
\sphinxAtStartPar
The goal is not of the form \sphinxcode{\sphinxupquote{\DUrole{name}{t} \DUrole{operator}{=} \DUrole{name}{u}}}. Especially note that {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.btauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{btauto}}}}}
doesn't introduce variables into the context on its own.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\subsection{Micromega: solvers for arithmetic goals over ordered rings}
\label{\detokenize{addendum/micromega:micromega-solvers-for-arithmetic-goals-over-ordered-rings}}\label{\detokenize{addendum/micromega:micromega}}\label{\detokenize{addendum/micromega::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
\sphinxAtStartPar
Frédéric Besson and Evgeny Makarov

\end{description}\end{quote}


\subsubsection{Short description of the tactics}
\label{\detokenize{addendum/micromega:short-description-of-the-tactics}}
\sphinxAtStartPar
The Psatz module (\sphinxcode{\sphinxupquote{Require Import Psatz.}}) gives access to several
tactics for solving arithmetic goals over \(\mathbb{Q}\),
\(\mathbb{R}\), and \(\mathbb{Z}\) but also \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}} and
\sphinxcode{\sphinxupquote{\DUrole{name}{N}}}.  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 {} 
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} is a decision procedure for linear integer arithmetic;

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/micromega:coq:tacn.nia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nia}}}}} is an incomplete proof procedure for integer non\sphinxhyphen{}linear
arithmetic;

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/micromega:coq:tacn.lra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lra}}}}} is a decision procedure for linear (real or rational) arithmetic;

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/micromega:coq:tacn.nra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nra}}}}} is an incomplete proof procedure for non\sphinxhyphen{}linear (real or
rational) arithmetic;

\item {} 
\sphinxAtStartPar
{\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\sphinxhyphen{}linear arithmetic.
It is based on John Harrison’s HOL Light
driver to the external prover \sphinxcode{\sphinxupquote{csdp}} %
\begin{footnote}[43]\sphinxAtStartFootnote
Sources and binaries can be found at \sphinxurl{https://projects.coin-or.org/Csdp}
%
\end{footnote}. Note that the \sphinxcode{\sphinxupquote{csdp}} driver
generates a \sphinxstyleemphasis{proof cache} which makes it possible to rerun scripts
even without \sphinxcode{\sphinxupquote{csdp}}.

\end{itemize}
\index{Simplex (flag)@\spxentry{Simplex}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:flag.Simplex}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Simplex}}}}~
\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.14.}

\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (set by default) instructs the decision procedures to
use the Simplex method for solving linear goals instead of the
deprecated Fourier elimination.

\end{fulllineitems}\end{savenotes}

\index{Dump Arith (option)@\spxentry{Dump Arith}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:opt.Dump-Arith}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Dump~Arith}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} (unset by default) may be set to a file path where
debug info will be written.

\end{fulllineitems}\end{savenotes}

\index{Show Lia Profile (command)@\spxentry{Show Lia Profile}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:cmd.Show-Lia-Profile}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Lia~Profile}}}}
\sphinxAtStartPar
This command prints some statistics about the amount of pivoting
operations needed by {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} and may be useful to detect
inefficiencies (only meaningful if flag {\hyperref[\detokenize{addendum/micromega:coq:flag.Simplex}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Simplex}}}}} is set).

\end{fulllineitems}\end{savenotes}

\index{Lia Cache (flag)@\spxentry{Lia Cache}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:flag.Lia-Cache}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Lia~Cache}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (set by default) instructs {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} to cache its results in the file \sphinxcode{\sphinxupquote{.lia.cache}}

\end{fulllineitems}\end{savenotes}

\index{Nia Cache (flag)@\spxentry{Nia Cache}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:flag.Nia-Cache}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nia~Cache}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (set by default) instructs {\hyperref[\detokenize{addendum/micromega:coq:tacn.nia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nia}}}}} to cache its results in the file \sphinxcode{\sphinxupquote{.nia.cache}}

\end{fulllineitems}\end{savenotes}

\index{Nra Cache (flag)@\spxentry{Nra Cache}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:flag.Nra-Cache}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nra~Cache}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} (set by default) instructs {\hyperref[\detokenize{addendum/micromega:coq:tacn.nra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nra}}}}} to cache its results in the file \sphinxcode{\sphinxupquote{.nra.cache}}

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
The tactics solve propositional formulas parameterized by atomic
arithmetic expressions interpreted over a domain \(D \in \{\mathbb{Z},\mathbb{Q},\mathbb{R}\}\).
The syntax for formulas over \(\mathbb{Z}\) is:
\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/micromega:grammar-token-F}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-A}]{\sphinxcrossref{\DUrole{hole}{A}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{P}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{True}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{False}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}} /\textbackslash{}\textbackslash{} {\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}} \textbackslash{}\textbackslash{}/ {\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}} <\sphinxhyphen{}> {\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}} \sphinxhyphen{}> {\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\textasciitilde{} {\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}} = {\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\DUrole{hole}{F}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/micromega:grammar-token-A}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/micromega:grammar-token-A}]{\sphinxcrossref{\DUrole{hole}{A}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} = {\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} > {\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} < {\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} >= {\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} <= {\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/micromega:grammar-token-p}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{c}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{x}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{−{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} − {\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} + {\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} * {\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{addendum/micromega:grammar-token-p}]{\sphinxcrossref{\DUrole{hole}{p}}}} \textasciicircum{} n}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}

\sphinxAtStartPar
where
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/micromega:grammar-token-F}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{F}}}}} is interpreted over either \sphinxcode{\sphinxupquote{Prop}} or \sphinxcode{\sphinxupquote{bool}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{P}}} is an arbitrary proposition

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{c}}} is a numeric constant of \(D\)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{x}}} \(\in D\) is a numeric variable

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{−}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{+}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{*}}} are respectively subtraction, addition and product

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{p \textasciicircum{} n}}} is exponentiation by a constant \(n\)

\end{itemize}

\sphinxAtStartPar
When \(F\) is interpreted over \sphinxcode{\sphinxupquote{bool}}, the boolean operators are
\sphinxcode{\sphinxupquote{\&\&}}, \sphinxcode{\sphinxupquote{||}}, \sphinxcode{\sphinxupquote{Bool.eqb}}, \sphinxcode{\sphinxupquote{Bool.implb}}, \sphinxcode{\sphinxupquote{Bool.negb}} and the comparisons
in \(A\) are also interpreted over the booleans (e.g., for
\(\mathbb{Z}\), we have \sphinxcode{\sphinxupquote{Z.eqb}}, \sphinxcode{\sphinxupquote{Z.gtb}}, \sphinxcode{\sphinxupquote{Z.ltb}}, \sphinxcode{\sphinxupquote{Z.geb}},
\sphinxcode{\sphinxupquote{Z.leb}}).

\sphinxAtStartPar
For \(\mathbb{Q}\), use the equality of rationals \sphinxcode{\sphinxupquote{==}} rather than
Leibniz equality \sphinxcode{\sphinxupquote{=}}.

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
c ::= R0 | R1 | Rmul(c,c) | Rplus(c,c) | Rminus(c,c) | IZR z | IQR q | Rdiv(c,c) | Rinv c
\end{sphinxVerbatim}

\sphinxAtStartPar
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.}, \sphinxcode{\sphinxupquote{c\%R}}.


\subsubsection{\sphinxstyleemphasis{Positivstellensatz} refutations}
\label{\detokenize{addendum/micromega:positivstellensatz-refutations}}
\sphinxAtStartPar
The name \sphinxcode{\sphinxupquote{psatz}} is an abbreviation for \sphinxstyleemphasis{positivstellensatz} – literally
"positivity theorem" – 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:

\sphinxAtStartPar
\(\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}\)

\sphinxAtStartPar
The following theorem provides a proof principle for checking that a
set of polynomial inequalities does not have solutions %
\begin{footnote}[44]\sphinxAtStartFootnote
Variants deal with equalities and strict inequalities.
%
\end{footnote}.

\phantomsection\label{\detokenize{addendum/micromega:psatz-thm}}
\sphinxAtStartPar
\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}\).

\sphinxAtStartPar
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 {\hyperref[\detokenize{addendum/ring:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} tactic (see {\hyperref[\detokenize{addendum/ring:theringandfieldtacticfamilies}]{\sphinxcrossref{\DUrole{std,std-ref}{ring and field: solvers for polynomial and rational equations}}}})
and checked to be \(-1\).


\subsubsection{\sphinxstyleliteralintitle{\sphinxupquote{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 (tactic)@\spxentry{lra}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.lra}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lra}}}}
\sphinxAtStartPar
This tactic is searching for \sphinxstyleemphasis{linear} refutations. As a result, this tactic explores a subset of the \sphinxstyleemphasis{Cone}
defined as

\sphinxAtStartPar
\(\mathit{LinCone}(S) =\left\{ \left. \sum_{p \in S} \alpha_p \times p~\right|~\alpha_p \mbox{ are positive constants} \right\}\)

\sphinxAtStartPar
The deductive power of {\hyperref[\detokenize{addendum/micromega:coq:tacn.lra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lra}}}}} overlaps with the one of {\hyperref[\detokenize{addendum/ring:coq:tacn.field}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{field}}}}}
tactic \sphinxstyleemphasis{e.g.}, \(x = 10 * x / 10\) is solved by {\hyperref[\detokenize{addendum/micromega:coq:tacn.lra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lra}}}}}.

\end{fulllineitems}\end{savenotes}



\subsubsection{\sphinxstyleliteralintitle{\sphinxupquote{lia}}: a tactic for linear integer arithmetic}
\label{\detokenize{addendum/micromega:lia-a-tactic-for-linear-integer-arithmetic}}\index{lia (tactic)@\spxentry{lia}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.lia}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lia}}}}
\sphinxAtStartPar
This tactic solves linear goals over \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}} by searching for \sphinxstyleemphasis{linear} refutations and cutting planes.
{\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} provides support for \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{positive}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{N}}} by pre\sphinxhyphen{}processing via the {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} tactic.

\end{fulllineitems}\end{savenotes}



\paragraph{High level view of \sphinxstyleliteralintitle{\sphinxupquote{lia}}}
\label{\detokenize{addendum/micromega:high-level-view-of-lia}}
\sphinxAtStartPar
Over \(\mathbb{R}\), \sphinxstyleemphasis{positivstellensatz} refutations are a complete proof
principle %
\begin{footnote}[45]\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 \to \mathtt{False}\)
which is a theorem of \(\mathbb{Z}\) but not a theorem of \({\mathbb{R}}\). To remedy this
weakness, the {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} tactic is using recursively a combination of:
\begin{itemize}
\item {} 
\sphinxAtStartPar
linear \sphinxstyleemphasis{positivstellensatz} refutations;

\item {} 
\sphinxAtStartPar
cutting plane proofs;

\item {} 
\sphinxAtStartPar
case split.

\end{itemize}


\paragraph{Cutting plane proofs}
\label{\detokenize{addendum/micromega:cutting-plane-proofs}}
\sphinxAtStartPar
are a way to take into account the discreteness of \(\mathbb{Z}\) by rounding up
(rational) constants up\sphinxhyphen{}to the closest integer.

\phantomsection\label{\detokenize{addendum/micromega:ceil-thm}}\index{Bound on the ceiling function (theorem)@\spxentry{Bound on the ceiling function}\spxextra{theorem}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:thm.Bound-on-the-ceiling-function}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Theorem}}} \sphinxbfcode{\sphinxupquote{Bound~on~the~ceiling~function}}}
\sphinxAtStartPar
Let \(p\) be an integer and \(c\) a rational constant. Then
\(p \ge c \rightarrow p \ge \lceil{c}\rceil\).

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
For instance, from \(2 x = 1\) we can deduce
\begin{itemize}
\item {} 
\sphinxAtStartPar
\(x \ge 1/2\) whose cut plane is \(x \ge \lceil{1/2}\rceil = 1\);

\item {} 
\sphinxAtStartPar
\(x \le 1/2\) whose cut plane is \(x \le \lfloor{1/2}\rfloor = 0\).

\end{itemize}

\sphinxAtStartPar
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})\).

\sphinxAtStartPar
Cutting plane proofs and linear \sphinxstyleemphasis{positivstellensatz} refutations are a
complete proof principle for integer linear arithmetic.


\paragraph{Case split}
\label{\detokenize{addendum/micromega:case-split}}
\sphinxAtStartPar
enumerates over the possible values of an expression.

\phantomsection\label{\detokenize{addendum/micromega:casesplit-thm}}
\sphinxAtStartPar
\sphinxstylestrong{Theorem}. Let \(p\) be an integer and \(c_1\) and \(c_2\)
integer constants. Then:
\begin{quote}

\sphinxAtStartPar
\(c_1 \le p \le c_2 \Rightarrow \bigvee_{x \in [c_1,c_2]} p = x\)
\end{quote}

\sphinxAtStartPar
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.


\subsubsection{\sphinxstyleliteralintitle{\sphinxupquote{nra}}: a proof procedure for non\sphinxhyphen{}linear arithmetic}
\label{\detokenize{addendum/micromega:nra-a-proof-procedure-for-non-linear-arithmetic}}\index{nra (tactic)@\spxentry{nra}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.nra}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{nra}}}}
\sphinxAtStartPar
This tactic is an \sphinxstyleemphasis{experimental} proof procedure for non\sphinxhyphen{}linear
arithmetic. The tactic performs a limited amount of non\sphinxhyphen{}linear
reasoning before running the linear prover of {\hyperref[\detokenize{addendum/micromega:coq:tacn.lra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lra}}}}}. This pre\sphinxhyphen{}processing
does the following:

\end{fulllineitems}\end{savenotes}

\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
After this pre\sphinxhyphen{}processing, the linear prover of {\hyperref[\detokenize{addendum/micromega:coq:tacn.lra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lra}}}}} searches for a
proof by abstracting monomials by variables.


\subsubsection{\sphinxstyleliteralintitle{\sphinxupquote{nia}}: a proof procedure for non\sphinxhyphen{}linear integer arithmetic}
\label{\detokenize{addendum/micromega:nia-a-proof-procedure-for-non-linear-integer-arithmetic}}\index{nia (tactic)@\spxentry{nia}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.nia}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{nia}}}}
\sphinxAtStartPar
This tactic is a proof procedure for non\sphinxhyphen{}linear integer arithmetic.
It performs a pre\sphinxhyphen{}processing similar to {\hyperref[\detokenize{addendum/micromega:coq:tacn.nra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nra}}}}}. The obtained goal is
solved using the linear integer prover {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}}.

\end{fulllineitems}\end{savenotes}



\subsubsection{\sphinxstyleliteralintitle{\sphinxupquote{psatz}}: a proof procedure for non\sphinxhyphen{}linear arithmetic}
\label{\detokenize{addendum/micromega:psatz-a-proof-procedure-for-non-linear-arithmetic}}\index{psatz (tactic)@\spxentry{psatz}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.psatz}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{psatz~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This tactic explores the \sphinxstyleemphasis{Cone} by increasing degrees – hence the
depth parameter {\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nat\_or\_var}}}}}. In theory, such a proof search is complete – if the
goal is provable the search eventually stops. Unfortunately, the
external oracle is using numeric (approximate) optimization techniques
that might miss a refutation.

\sphinxAtStartPar
To illustrate the working of the tactic, consider we wish to prove the
following Coq goal:

\end{fulllineitems}\end{savenotes}


\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ZArith} \PYG{n}{Psatz}\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{k}{intro} \PYG{n}{x}\PYG{o}{.}
\PYG{n}{psatz} \PYG{n}{Z} \PYG{l+m+mi}{2}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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 {\hyperref[\detokenize{addendum/ring:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} we
obtain \(-1\). By Theorem {\hyperref[\detokenize{addendum/micromega:psatz-thm}]{\sphinxcrossref{\DUrole{std,std-ref}{Psatz}}}}, the goal is valid.


\subsubsection{\sphinxstyleliteralintitle{\sphinxupquote{zify}}: pre\sphinxhyphen{}processing of arithmetic goals}
\label{\detokenize{addendum/micromega:zify-pre-processing-of-arithmetic-goals}}\index{zify (tactic)@\spxentry{zify}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.zify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{zify}}}}
\sphinxAtStartPar
This tactic is internally called by {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} to support additional types, e.g., \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{positive}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{N}}}.
Additional support is provided by the following modules:
\begin{itemize}
\item {} 
\sphinxAtStartPar
For boolean operators (e.g., \sphinxcode{\sphinxupquote{\DUrole{name}{Nat}\DUrole{operator}{.}\DUrole{name}{leb}}}), require the module \sphinxcode{\sphinxupquote{\DUrole{name}{ZifyBool}}}.

\item {} 
\sphinxAtStartPar
For comparison operators (e.g., \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{compare}}}), require the module \sphinxcode{\sphinxupquote{\DUrole{name}{ZifyComparison}}}.

\item {} 
\sphinxAtStartPar
For native unsigned 63 bit integers, require the module \sphinxcode{\sphinxupquote{\DUrole{name}{ZifyUint63}}}.

\item {} 
\sphinxAtStartPar
For native signed 63 bit integers, require the module \sphinxcode{\sphinxupquote{\DUrole{name}{ZifySint63}}}.

\item {} 
\sphinxAtStartPar
For operators \sphinxcode{\sphinxupquote{\DUrole{name}{Nat}\DUrole{operator}{.}\DUrole{name}{div}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Nat}\DUrole{operator}{.}\DUrole{name}{mod}}}, and \sphinxcode{\sphinxupquote{\DUrole{name}{Nat}\DUrole{operator}{.}\DUrole{name}{pow}}}, require the module \sphinxcode{\sphinxupquote{\DUrole{name}{ZifyNat}}}.

\item {} 
\sphinxAtStartPar
For operators \sphinxcode{\sphinxupquote{\DUrole{name}{N}\DUrole{operator}{.}\DUrole{name}{div}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{N}\DUrole{operator}{.}\DUrole{name}{mod}}}, and \sphinxcode{\sphinxupquote{\DUrole{name}{N}\DUrole{operator}{.}\DUrole{name}{pow}}}, require the module \sphinxcode{\sphinxupquote{\DUrole{name}{ZifyN}}}.

\end{itemize}

\sphinxAtStartPar
{\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} can also be extended by rebinding the tactics \sphinxcode{\sphinxupquote{Zify.zify\_pre\_hook}} and \sphinxcode{\sphinxupquote{Zify.zify\_post\_hook}} that are
respectively run in the first and the last steps of {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}}.
\begin{itemize}
\item {} 
\sphinxAtStartPar
To support \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{div}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{modulo}}}: \sphinxcode{\sphinxupquote{Ltac Zify.zify\_post\_hook ::= Z.div\_mod\_to\_equations}}.

\item {} 
\sphinxAtStartPar
To support \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{quot}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{rem}}}: \sphinxcode{\sphinxupquote{Ltac Zify.zify\_post\_hook ::= Z.quot\_rem\_to\_equations}}.

\item {} 
\sphinxAtStartPar
To support \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{div}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{modulo}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{quot}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{rem}}}: either \sphinxcode{\sphinxupquote{Ltac Zify.zify\_post\_hook ::= Z.to\_euclidean\_division\_equations}} or \sphinxcode{\sphinxupquote{Ltac Zify.zify\_convert\_to\_euclidean\_division\_equations\_flag ::= constr:(true)}}.

\end{itemize}

\sphinxAtStartPar
The {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} tactic can be extended with new types and operators by declaring and registering new typeclass instances using the following commands.
The typeclass declarations can be found in the module \sphinxcode{\sphinxupquote{ZifyClasses}} and the default instances can be found in the module \sphinxcode{\sphinxupquote{ZifyInst}}.

\end{fulllineitems}\end{savenotes}

\index{Add Zify (command)@\spxentry{Add Zify}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:cmd.Add-Zify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Zify~{\hyperref[\detokenize{addendum/micromega:grammar-token-add_zify}]{\sphinxcrossref{\DUrole{hole}{add\_zify}}}}~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/micromega:grammar-token-add_zify}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/micromega:grammar-token-add_zify}]{\sphinxcrossref{\DUrole{hole}{add\_zify}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{InjTyp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{BinOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{UnOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{CstOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{BinRel}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{UnOpSpec}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{BinOpSpec}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{PropOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{PropBinOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{PropUOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Saturate}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Registers an instance of the specified typeclass.
The typeclass type (e.g. \sphinxcode{\sphinxupquote{\DUrole{name}{BinOp} \DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{mul}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{BinRel} \DUrole{operator}{(@}\DUrole{name}{eq} \DUrole{name}{Z}\DUrole{operator}{)}}}) has the additional constraint that
the non\sphinxhyphen{}implicit argument (here, \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{mul}}} or \sphinxcode{\sphinxupquote{\DUrole{operator}{(@}\DUrole{name}{eq} \DUrole{name}{Z}\DUrole{operator}{)}}})
is either a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} (here, \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{mul}}}) or the application of a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} (here, \sphinxcode{\sphinxupquote{\DUrole{operator}{@}\DUrole{name}{eq}}}) to a sequence of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Show Zify (command)@\spxentry{Show Zify}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:cmd.Show-Zify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Zify~{\hyperref[\detokenize{addendum/micromega:grammar-token-show_zify}]{\sphinxcrossref{\DUrole{hole}{show\_zify}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/micromega:grammar-token-show_zify}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/micromega:grammar-token-show_zify}]{\sphinxcrossref{\DUrole{hole}{show\_zify}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{InjTyp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{BinOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{UnOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{CstOp}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{BinRel}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{UnOpSpec}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{BinOpSpec}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Spec}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Prints instances for the specified typeclass.  For instance, {\hyperref[\detokenize{addendum/micromega:coq:cmd.Show-Zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Zify}}}}} \sphinxcode{\sphinxupquote{InjTyp}}
prints the list of types that supported by {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} i.e.,
\sphinxcode{\sphinxupquote{\DUrole{name}{Z}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{positive}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{N}}}.

\end{fulllineitems}\end{savenotes}



\subsection{ring and field: solvers for polynomial and rational equations}
\label{\detokenize{addendum/ring:ring-and-field-solvers-for-polynomial-and-rational-equations}}\label{\detokenize{addendum/ring:theringandfieldtacticfamilies}}\label{\detokenize{addendum/ring::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
\sphinxAtStartPar
Bruno Barras, Benjamin Grégoire, Assia Mahboubi, Laurent Théry %
\begin{footnote}[46]\sphinxAtStartFootnote
based on previous work from Patrick Loiseleur and Samuel Boutin
%
\end{footnote}

\end{description}\end{quote}

\sphinxAtStartPar
This chapter presents the tactics dedicated to dealing with ring and
field equations.


\subsubsection{What does this tactic do?}
\label{\detokenize{addendum/ring:what-does-this-tactic-do}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ring}} does associative\sphinxhyphen{}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\).

\sphinxAtStartPar
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}

\sphinxAtStartPar
In the ring of integers, the normal form of
\begin{quote}

\sphinxAtStartPar
\(x (3 + yx + 25(1 − z)) + zx\)
\end{quote}

\sphinxAtStartPar
is
\begin{quote}

\sphinxAtStartPar
\(28x + (−24)xz + xxy\).
\end{quote}
\end{sphinxadmonition}

\sphinxAtStartPar
\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\).


\subsubsection{The variables map}
\label{\detokenize{addendum/ring:the-variables-map}}
\sphinxAtStartPar
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}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(plus (mult (plus (f (5)) x) x)
      (mult (if b then (4) else (f (3))) (2)))
\end{sphinxVerbatim}

\sphinxAtStartPar
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

\sphinxAtStartPar
0
&
\sphinxAtStartPar
\(\mapsto\)
&
\sphinxAtStartPar
if b then (4) else (f (3))
\\
\hline
\sphinxAtStartPar
1
&
\sphinxAtStartPar
\(\mapsto\)
&
\sphinxAtStartPar
(f (5))
\\
\hline
\sphinxAtStartPar
2
&
\sphinxAtStartPar
\(\mapsto\)
&
\sphinxAtStartPar
x
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\sphinxAtStartPar
Then normalize the “abstract” polynomial
\(((V_1 \oplus V_2 ) \otimes 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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(plus (mult (2) (if b then (4) else (f (3))))
      (plus (mult (f (5)) x) (mult x x)))
\end{sphinxVerbatim}


\subsubsection{Is it automatic?}
\label{\detokenize{addendum/ring:is-it-automatic}}
\sphinxAtStartPar
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.


\subsubsection{Concrete usage in Coq}
\label{\detokenize{addendum/ring:concrete-usage-in-coq}}\index{ring (tactic)@\spxentry{ring}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:tacn.ring}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring~\DUrole{repeat-wrapper}{\DUrole{repeat}{{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}~{]}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Solves polynomical equations 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
syntactically comparing the results.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}} {]}}}}}] \leavevmode
\sphinxAtStartPar
If specified, the tactic decides the equality of two terms modulo ring operations and
the equalities defined by the {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s.
Each {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}} has to be a proof of some equality \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{=} \DUrole{name}{p}}}, where \sphinxcode{\sphinxupquote{\DUrole{name}{m}}}
is a monomial (after “abstraction”), \sphinxcode{\sphinxupquote{\DUrole{name}{p}}} a polynomial and \sphinxcode{\sphinxupquote{\DUrole{operator}{=}}} is the
corresponding equality of the ring structure.

\end{description}

\end{fulllineitems}\end{savenotes}

\index{ring\_simplify (tactic)@\spxentry{ring\_simplify}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:tacn.ring_simplify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring\_simplify~\DUrole{repeat-wrapper}{\DUrole{repeat}{{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}~{]}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Applies the normalization procedure described above to
the given {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s. The tactic then replaces all occurrences of the {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s
given in the conclusion of the goal by their normal forms. If no {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}
is given, then the conclusion should be an equation and both
sides are normalized. The tactic can also be applied in a hypothesis.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{in {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
If specified, the tactic performs the simplification in the hypothesis named {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{description}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{ring\_simplify {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{1}}$}}}}; ring\_simplify {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{2}}$}}}}}}} is not equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{ring\_simplify {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{2}}$}}}}}}}.

\sphinxAtStartPar
In the latter case the variables map is shared between the two {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s, and
common subterm \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{2}}$}}}}}}}
will have the same associated variable number. So the first
alternative should be avoided for {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s belonging to the same ring
theory.
\end{sphinxadmonition}

\sphinxAtStartPar
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}}.

\sphinxAtStartPar
All declared field structures can be printed with the {\hyperref[\detokenize{addendum/ring:coq:cmd.Print-Rings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Rings}}}}} command.
\index{Print Rings (command)@\spxentry{Print Rings}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:cmd.Print-Rings}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Rings}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\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}{ring\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}{zify\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}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}\PYG{o}{.}

\PYG{k+kn}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}\PYG{o}{.}

\PYG{k+kn}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Error messages:
\index{Not a valid ring equation (error)@\spxentry{Not a valid ring equation}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
The conclusion of the goal is not provable in the corresponding ring theory.

\end{fulllineitems}\end{savenotes}

\index{Arguments of ring\_simplify do not have all the same type (error)@\spxentry{Arguments of ring\_simplify do not have all the same type}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/ring:coq:tacn.ring_simplify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring\_simplify}}}}} cannot simplify terms of several rings at the same
time. Invoke the tactic once per ring structure.

\end{fulllineitems}\end{savenotes}

\index{Cannot find a declared ring structure over ‘term’ (error)@\spxentry{Cannot find a declared ring structure over ‘term’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.Cannot-find-a-declared-ring-structure-over-_u2018term_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~a~declared~ring~structure~over~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
\sphinxAtStartPar
No ring has been declared for the type of the terms to be simplified.
Use {\hyperref[\detokenize{addendum/ring:coq:cmd.Add-Ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add Ring}}}}} first.

\end{fulllineitems}\end{savenotes}

\index{Cannot find a declared ring structure for equality ‘term’ (error)@\spxentry{Cannot find a declared ring structure for equality ‘term’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.Cannot-find-a-declared-ring-structure-for-equality-_u2018term_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~a~declared~ring~structure~for~equality~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
\sphinxAtStartPar
Same as above in the case of the {\hyperref[\detokenize{addendum/ring:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} tactic.

\end{fulllineitems}\end{savenotes}



\subsubsection{Adding a ring structure}
\label{\detokenize{addendum/ring:adding-a-ring-structure}}
\sphinxAtStartPar
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\sphinxhyphen{}
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:

\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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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:

\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}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{c0}} and \sphinxcode{\sphinxupquote{cI}} denote the 0 and 1 of the coefficient set, \sphinxcode{\sphinxupquote{+!}}, \sphinxcode{\sphinxupquote{*!}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}!}}
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.

\sphinxAtStartPar
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\sphinxhyphen{})rings:
\begin{description}
\item[{abstract rings}] \leavevmode
\sphinxAtStartPar
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
\sphinxAtStartPar
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
\sphinxAtStartPar
for other cases. The user has to provide the
coefficient set and the morphism.

\end{description}

\sphinxAtStartPar
This implementation of ring can also recognize simple power
expressions as ring expressions. A power function is specified by the
following property:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Reals}\PYG{o}{.}
\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}{rpow} \PYG{n}{r} \PYG{o}{(}\PYG{n}{Cp\PYGZus{}phi} \PYG{n}{n}\PYG{o}{)} \PYG{o}{=} \PYG{n}{pow\PYGZus{}N} \PYG{l+m+mi}{1}\PYG{o}{\PYGZpc{}}\PYG{n}{R} \PYG{n}{Rmult} \PYG{n}{r} \PYG{n}{n}
  \PYG{o}{\PYGZcb{}}\PYG{o}{.}

\PYG{k+kn}{End} \PYG{n}{POWER}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The syntax for adding a new ring is
\index{Add Ring (command)@\spxentry{Add Ring}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/ring:grammar-token-ring_mod}]{\sphinxcrossref{\DUrole{hole}{ring\_mod}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~)}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/ring:grammar-token-ring_mod}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/ring:grammar-token-ring_mod}]{\sphinxcrossref{\DUrole{hole}{ring\_mod}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{decidable {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{abstract}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{morphism {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{constants {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{preprocess {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{postprocess {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{setoid {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{sign {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{power {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{power\_tac {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{div {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{closed {[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is used only for error messages. The
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is a proof that the ring signature satisfies the (semi\sphinxhyphen{})ring
axioms. The optional list of modifiers is used to tailor the behavior
of the tactic. Here are their effects:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{abstract}}}}] \leavevmode
\sphinxAtStartPar
declares the ring as abstract. This is the default.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{decidable {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
declares the ring as computational. The expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is the correctness proof of an equality test \sphinxcode{\sphinxupquote{?=!}}
(which should be evaluable). Its type should be of the form
\sphinxcode{\sphinxupquote{forall x y, x ?=! y = true → x == y}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{morphism {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
declares the ring as a customized one. The expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_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[{\sphinxcode{\sphinxupquote{\DUrole{notation}{setoid {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
forces the use of given setoid. The first
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is a proof that the equality is indeed a setoid (see
\sphinxcode{\sphinxupquote{Setoid.Setoid\_Theory}}), and the second 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[{\sphinxcode{\sphinxupquote{\DUrole{notation}{constants {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
specifies a tactic expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} 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[{\sphinxcode{\sphinxupquote{\DUrole{notation}{preprocess {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
specifies a tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} that is applied as a
preliminary step for {\hyperref[\detokenize{addendum/ring:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} and {\hyperref[\detokenize{addendum/ring:coq:tacn.ring_simplify}]{\sphinxcrossref{\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[{\sphinxcode{\sphinxupquote{\DUrole{notation}{postprocess {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
specifies a tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} that is applied as a final
step for {\hyperref[\detokenize{addendum/ring:coq:tacn.ring_simplify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring\_simplify}}}}}. For instance, it can be used to undo
modifications of the preprocessor.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{power {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} {]}}}}}] \leavevmode
\sphinxAtStartPar
to be documented

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{power\_tac {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
allows {\hyperref[\detokenize{addendum/ring:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} and {\hyperref[\detokenize{addendum/ring:coq:tacn.ring_simplify}]{\sphinxcrossref{\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/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_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}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}} 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. \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ is the inverse function of
\sphinxcode{\sphinxupquote{Cp\_phi}}). See files \sphinxcode{\sphinxupquote{plugins/ring/ZArithRing.v}}
and \sphinxcode{\sphinxupquote{plugins/ring/RealField.v}} for examples. By default the tactic
does not recognize power expressions as ring expressions.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{sign {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
allows {\hyperref[\detokenize{addendum/ring:coq:tacn.ring_simplify}]{\sphinxcrossref{\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 {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is a proof that a given sign function indicates expressions
that are signed ({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} has to be a proof of \sphinxcode{\sphinxupquote{Ring\_theory.get\_sign}}). See
\sphinxcode{\sphinxupquote{plugins/ring/InitialRing.v}} for examples of sign function.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{div {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
allows {\hyperref[\detokenize{addendum/ring:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} and {\hyperref[\detokenize{addendum/ring:coq:tacn.ring_simplify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring\_simplify}}}}} to use monomials with
coefficients other than 1 in the rewriting. The term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is a proof
that a given division function satisfies the specification of an
euclidean division function (\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_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/ring/InitialRing.v}} for examples of div function.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{closed {[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} {]}}}}}] \leavevmode
\sphinxAtStartPar
to be documented

\end{description}

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Error messages:
\index{Bad ring structure (error)@\spxentry{Bad ring structure}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
The proof of the ring structure provided is not
of the expected type.

\end{fulllineitems}\end{savenotes}

\index{Bad lemma for decidability of equality (error)@\spxentry{Bad lemma for decidability of equality}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
The equality function
provided in the case of a computational ring has not the expected
type.

\end{fulllineitems}\end{savenotes}

\index{Ring operation should be declared as a morphism (error)@\spxentry{Ring operation should be declared as a morphism}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
A setoid associated with 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}\end{savenotes}



\subsubsection{How does it work?}
\label{\detokenize{addendum/ring:how-does-it-work}}
\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ or 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.

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{PExpr} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
  \PYG{o}{|} \PYG{n}{PEc} \PYG{o}{:} \PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{|} \PYG{n}{PEX} \PYG{o}{:} \PYG{n}{positive} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{|} \PYG{n}{PEadd} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{|} \PYG{n}{PEsub} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{|} \PYG{n}{PEmul} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{|} \PYG{n}{PEopp} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{|} \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}

\sphinxAtStartPar
Polynomials in normal form are defined as:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Pol} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
  \PYG{o}{|} \PYG{n}{Pc} \PYG{o}{:} \PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol}
  \PYG{o}{|} \PYG{n}{Pinj} \PYG{o}{:} \PYG{n}{positive} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol}
  \PYG{o}{|} \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}

\sphinxAtStartPar
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'\), \sphinxcode{\sphinxupquote{Q'}} being \sphinxcode{\sphinxupquote{Q}} where \(V_i\) is replaced by \(V_{i+1}\).

\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{PEeval} \PYG{o}{:} \PYG{n}{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{n}{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}

\sphinxAtStartPar
A function to normalize polynomials is defined, and the big theorem is
its correctness w.r.t interpretation, that is:

\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}

\sphinxAtStartPar
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 ML code guesses the type of \sphinxcode{\sphinxupquote{p}}, the ring theory \sphinxcode{\sphinxupquote{T}} to use, an
abstract polynomial \sphinxcode{\sphinxupquote{ap}} and a variables map \sphinxcode{\sphinxupquote{v}} such that \sphinxcode{\sphinxupquote{p}} is βδι\sphinxhyphen{}
equivalent to \sphinxcode{\sphinxupquote{(PEeval v ap)}}. Then we replace it by \sphinxcode{\sphinxupquote{(Pphi\_dev v (norm ap))}},
using the main correctness theorem and we reduce it to a
concrete expression \sphinxcode{\sphinxupquote{p’}}, which is the concrete normal form of \sphinxcode{\sphinxupquote{p}}. This is summarized in this diagram:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{p}}
&
\sphinxAtStartPar
\(\rightarrow_{\beta\delta\iota}\)
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{(PEeval}} \sphinxcode{\sphinxupquote{v}} \sphinxcode{\sphinxupquote{ap}}\sphinxcode{\sphinxupquote{)}}
\\
\hline
\sphinxAtStartPar

&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{=}}$_{\text{(by the main correctness theorem)}}$
&
\sphinxAtStartPar

\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{p’}}
&
\sphinxAtStartPar
\(\leftarrow_{\beta\delta\iota}\)
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{(Pphi\_dev}} \sphinxcode{\sphinxupquote{v}} \sphinxcode{\sphinxupquote{(norm}} \sphinxcode{\sphinxupquote{ap}}\sphinxcode{\sphinxupquote{))}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\sphinxAtStartPar
The user does not see the right part of the diagram. From outside, the
tactic behaves like a βδι simplification extended with rewriting rules
for associativity and commutativity. Basically, the proof is only the
application of the main correctness theorem to well\sphinxhyphen{}chosen arguments.


\subsubsection{Dealing with fields}
\label{\detokenize{addendum/ring:dealing-with-fields}}\index{field (tactic)@\spxentry{field}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:tacn.field}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field~\DUrole{repeat-wrapper}{\DUrole{repeat}{{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}~{]}}\DUrole{notation-sup}{?}}}}}}~\begin{quote}

\sphinxAtStartPar
An extension of the {\hyperref[\detokenize{addendum/ring:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} tactic that deals with rational
expressions. Given a rational expression \(F = 0\). It first reduces the
expression \sphinxcode{\sphinxupquote{F}} to a common denominator \(N/D = 0\) where \sphinxcode{\sphinxupquote{N}} and \sphinxcode{\sphinxupquote{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\).
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}} {]}}}}}] \leavevmode
\sphinxAtStartPar
If specified, the tactic decides the equality of two terms modulo
field operations and the equalities defined
by the {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s. Each {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}} has to be a proof of some equality
\sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{=} \DUrole{name}{p}}}, where \sphinxcode{\sphinxupquote{\DUrole{name}{m}}} is a monomial (after “abstraction”), \sphinxcode{\sphinxupquote{\DUrole{name}{p}}} a polynomial
and \sphinxcode{\sphinxupquote{\DUrole{operator}{=}}} the corresponding equality of the field structure.

\end{description}
\end{quote}

\begin{sphinxadmonition}{note}{Note:}\begin{quote}

\sphinxAtStartPar
Rewriting works with the equality  \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{=} \DUrole{name}{p}}} only if \sphinxcode{\sphinxupquote{\DUrole{name}{p}}} is a polynomial since
rewriting is handled by the underlying ring tactic.
\end{quote}

\sphinxAtStartPar
Note that \sphinxcode{\sphinxupquote{\DUrole{notation}{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.

\sphinxAtStartPar
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/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}}.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\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}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}\PYG{o}{.}

\PYG{k+kn}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}\PYG{o}{.}

\PYG{k+kn}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: \sphinxstyleliteralintitle{\sphinxupquote{field}} that generates side goals}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Reals}\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal}
      
      \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}
\index{field\_simplify (tactic)@\spxentry{field\_simplify}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:tacn.field_simplify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify~\DUrole{repeat-wrapper}{\DUrole{repeat}{{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{eq}}$}}}}}\DUrole{notation-sup}{+}}~{]}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
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.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{eq}}$}}}}}\DUrole{notation-sup}{+}} {]}}}}}] \leavevmode
\sphinxAtStartPar
Do simplification in the conclusion of the goal using the equalities
defined by these {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}}}}}] \leavevmode
\sphinxAtStartPar
Terms to simplify in the conclusion.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{in {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
If specified, substitute in the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} instead of the conclusion.

\end{description}

\end{fulllineitems}\end{savenotes}

\index{field\_simplify\_eq (tactic)@\spxentry{field\_simplify\_eq}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:tacn.field_simplify_eq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify\_eq~\DUrole{repeat-wrapper}{\DUrole{repeat}{{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}~{]}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
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\).
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}} {]}}}}}] \leavevmode
\sphinxAtStartPar
Do simplification in the conclusion of the goal using the equalities
defined by these {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_term}}}}}s.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{in {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
If specified, simplify in the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} instead of the conclusion.

\end{description}

\end{fulllineitems}\end{savenotes}



\subsubsection{Adding a new field structure}
\label{\detokenize{addendum/ring:adding-a-new-field-structure}}
\sphinxAtStartPar
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\sphinxhyphen{}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:

\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}

\sphinxAtStartPar
The result of the normalization process is a fraction represented by
the following type:

\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{n}{list} \PYG{o}{(}\PYG{n}{PExpr} \PYG{n}{C}\PYG{o}{)}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\sphinxAtStartPar
The syntax for adding a new field is
\index{Add Field (command)@\spxentry{Add Field}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/ring:grammar-token-field_mod}]{\sphinxcrossref{\DUrole{hole}{field\_mod}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~)}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/ring:grammar-token-field_mod}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/ring:grammar-token-field_mod}]{\sphinxcrossref{\DUrole{hole}{field\_mod}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{addendum/ring:grammar-token-ring_mod}]{\sphinxcrossref{\DUrole{hole}{ring\_mod}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{completeness {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is used only for error
messages. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is a proof that the field signature satisfies the
(semi\sphinxhyphen{})field axioms. The optional list of modifiers is used to tailor
the behavior of the tactic.

\sphinxAtStartPar
Since field tactics are built upon \sphinxcode{\sphinxupquote{ring}}
tactics, all modifiers of {\hyperref[\detokenize{addendum/ring:coq:cmd.Add-Ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add Ring}}}}} apply. There is only one
specific modifier:
\begin{description}
\item[{completeness \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
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/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is a proof of
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y}\DUrole{operator}{,} \DUrole{operator}{{[}}\DUrole{name}{x}\DUrole{operator}{{]}} \DUrole{operator}{==} \DUrole{operator}{{[}}\DUrole{name}{y}\DUrole{operator}{{]}} \DUrole{operator}{\sphinxhyphen{}>}  \DUrole{name}{x} \DUrole{operator}{?=!} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{name,builtin,pseudo}{true}}},
which is the completeness of equality on coefficients
w.r.t. the field equality.

\end{description}

\end{fulllineitems}\end{savenotes}



\subsubsection{History of ring}
\label{\detokenize{addendum/ring:history-of-ring}}
\sphinxAtStartPar
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 Coq’s type checker. Let us see why:

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}\PYG{o}{.}

\PYG{k+kn}{Save} \PYG{n}{foo}\PYG{o}{.}
\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{k+kn}{Arguments} \PYG{n}{foo} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z\PYGZus{}scope}
\end{sphinxVerbatim}

\sphinxAtStartPar
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 {[}\hyperlink{cite.zebibliography:id4}{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 βδι\sphinxhyphen{}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 ML code for the \sphinxcode{\sphinxupquote{Add Ring}} command that allows registering new rings dynamically.

\sphinxAtStartPar
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.


\subsubsection{Discussion}
\label{\detokenize{addendum/ring:discussion}}\label{\detokenize{addendum/ring:discussion-reflection}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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\sphinxhyphen{}effects and backtracking, and generate a small proof term.
Clearly, it would be significantly less efficient to replace them by
tactics using reflection.

\sphinxAtStartPar
Another idea suggested by Benjamin Werner: reflection could be used to
couple an external tool (a rewriting program or a model checker)
with Coq. We define (in 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\sphinxhyphen{}effects, backtracking, exception, or others
features that are not available in pure lambda calculus) to produce
the trace. Now we can check in Coq that the trace has the expected
semantics by applying the correctness theorem.


\subsection{Nsatz: a solver for equalities in integral domains}
\label{\detokenize{addendum/nsatz:nsatz-a-solver-for-equalities-in-integral-domains}}\label{\detokenize{addendum/nsatz:nsatz-chapter}}\label{\detokenize{addendum/nsatz::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
\sphinxAtStartPar
Loïc Pottier

\end{description}\end{quote}

\sphinxAtStartPar
To use the tactics described in this section, load the \sphinxcode{\sphinxupquote{Nsatz}} module with the
command \sphinxcode{\sphinxupquote{Require Import Nsatz}}.  Alternatively, if you prefer not to transitively depend on the
files that declare the axioms used to define the real numbers, you can
\sphinxcode{\sphinxupquote{Require Import NsatzTactic}} instead; this will still allow
{\hyperref[\detokenize{addendum/nsatz:coq:tacn.nsatz}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nsatz}}}}} to solve goals defined about \(\mathbb{Z}\),
\(\mathbb{Q}\) and any user\sphinxhyphen{}registered rings.
\index{nsatz (tactic)@\spxentry{nsatz}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/nsatz:coq:tacn.nsatz}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{nsatz~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~radicalmax~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~strategy~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~parameters~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~variables~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
This tactic is for solving goals of the form

\sphinxAtStartPar
\(\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}\)

\sphinxAtStartPar
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.

\sphinxAtStartPar
It also proves formulas

\sphinxAtStartPar
\(\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}\)

\sphinxAtStartPar
doing automatic introductions.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{radicalmax}}}] \leavevmode
\sphinxAtStartPar
bound when searching for r such that
\(c (P−Q) r = \sum_{i=1..s} S_i (P i − Q i)\).
This argument must be of type \sphinxcode{\sphinxupquote{N}} (binary natural numbers).

\item[{\sphinxcode{\sphinxupquote{strategy}}}] \leavevmode
\sphinxAtStartPar
gives the order on variables \(X_1,\ldots,X_n\) and the strategy
used in Buchberger algorithm (see {[}\hyperlink{cite.zebibliography:id50}{GMN+91}{]} for details):
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{strategy := 0\%Z}}: reverse lexicographic order and newest s\sphinxhyphen{}polynomial.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{strategy := 1\%Z}}: reverse lexicographic order and sugar strategy.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{strategy := 2\%Z}}: pure lexicographic order and newest s\sphinxhyphen{}polynomial.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{strategy := 3\%Z}}: pure lexicographic order and sugar strategy.

\end{itemize}

\item[{\sphinxcode{\sphinxupquote{parameters}}}] \leavevmode
\sphinxAtStartPar
a list of parameters of type \sphinxcode{\sphinxupquote{R}}, containing the variables \(X_{i_1},\ldots,X_{i_k}\) among
\(X_1,\ldots,X_n\).  Computation will be performed with
rational fractions in these parameters, i.e. polynomials have
coefficients in \(R(X_{i_1},\ldots,X_{i_k})\). In this case, the coefficient
\(c\) can be a nonconstant polynomial in \(X_{i_1},\ldots,X_{i_k}\), and the tactic
produces a goal which states that \(c\) is not zero.

\item[{\sphinxcode{\sphinxupquote{variables}}}] \leavevmode
\sphinxAtStartPar
a list of variables of type \sphinxcode{\sphinxupquote{R}} in the decreasing order in
which they will be used in the Buchberger algorithm. If the list is empty,
then \sphinxcode{\sphinxupquote{lvar}} is replaced by all the variables which are not in
\sphinxcode{\sphinxupquote{parameters}}.

\end{description}

\sphinxAtStartPar
See the file \sphinxhref{https://github.com/coq/coq/blob/master/test-suite/success/Nsatz.v}{Nsatz.v}%
\begin{footnote}[47]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/blob/master/test-suite/success/Nsatz.v}
%
\end{footnote}
for examples, especially in geometry.

\end{fulllineitems}\end{savenotes}



\subsubsection{More about \sphinxstyleliteralintitle{\sphinxupquote{nsatz}}}
\label{\detokenize{addendum/nsatz:more-about-nsatz}}
\sphinxAtStartPar
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).

\sphinxAtStartPar
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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}{Typeclasses}}}}.


\subsection{Programmable proof search}
\label{\detokenize{proofs/automatic-tactics/auto:programmable-proof-search}}\label{\detokenize{proofs/automatic-tactics/auto:automation}}\label{\detokenize{proofs/automatic-tactics/auto::doc}}\index{auto (tactic)@\spxentry{auto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{auto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{using \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{with *}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{with \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Implements a Prolog\sphinxhyphen{}like resolution procedure to solve the
current goal. It first tries to solve the goal using the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assumption}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assumption}}}}}
tactic, then it reduces the goal to an atomic one using {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}} and
introduces the newly generated hypotheses as hints. Then it looks at
the list of tactics associated with the head symbol of the goal and
tries to apply one of them.  Lower cost tactics are tried before higher\sphinxhyphen{}cost
tactics.  This process is recursively applied to the generated subgoals.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}}}}] \leavevmode
\sphinxAtStartPar
Specifies the maximum search depth.  The default is 5.

\end{description}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{using \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}
\begin{quote}

\sphinxAtStartPar
Uses lemmas \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}} in addition to hints. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is an
inductive type, the collection of its constructors are added as hints.

\sphinxAtStartPar
Note that hints passed through the \sphinxcode{\sphinxupquote{using}} clause are used in the same
way as if they were passed through a hint database. Consequently,
they use a weaker version of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{auto using {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}
may fail where \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} succeeds.
\end{quote}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{with *}}}}] \leavevmode
\sphinxAtStartPar
Use all existing hint databases. Using this variant is highly discouraged
in finished scripts since it is both slower and less robust than explicitly
selecting the required databases.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{with \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}] \leavevmode
\sphinxAtStartPar
Use the hint databases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} in addition to the database \sphinxcode{\sphinxupquote{core}}.
Use the fake database \sphinxcode{\sphinxupquote{nocore}} to omit \sphinxcode{\sphinxupquote{core}}.

\end{description}

\sphinxAtStartPar
If no \sphinxcode{\sphinxupquote{with}} clause is given, {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} only uses the hypotheses of the
current goal and the hints of the database named \sphinxcode{\sphinxupquote{core}}.

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} generally either completely solves the goal or
leaves it unchanged.  Use {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}} \sphinxcode{\sphinxupquote{{[} auto {]}}} if you want a failure
when they don't solve the goal.  {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} will fail if {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fail}}}}}
or {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.gfail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gfail}}}}} are invoked directly or indirectly, in which case setting
the {\hyperref[\detokenize{proof-engine/ltac:coq:flag.Ltac-Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac Debug}}}}} may help you debug the failure.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} uses a weaker version of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} that is closer to
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple apply}}}}} so it is expected that sometimes {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} will
fail even if applying manually one of the hints would succeed.
\end{sphinxadmonition}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The hints databases for auto and eauto}}}} for the list of
pre\sphinxhyphen{}defined databases and the way to create or extend a database.


\index{info\_auto (tactic)@\spxentry{info\_auto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.info_auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{info\_auto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Behaves like {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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}\end{savenotes}

\index{debug auto (tactic)@\spxentry{debug auto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.debug-auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{debug~auto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Behaves like {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} but shows the tactics it tries to solve the goal,
including failing paths.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{trivial (tactic)@\spxentry{trivial}\spxextra{tactic}}\index{debug trivial (tactic)@\spxentry{debug trivial}\spxextra{tactic}}\index{info\_trivial (tactic)@\spxentry{info\_trivial}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{trivial~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.debug-trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{debug~trivial~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.info_trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{info\_trivial~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Like {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}, but is not recursive
and only tries hints with zero cost. Typically used to solve goals
for which a lemma is already available in the specified \sphinxcode{\sphinxupquote{\DUrole{notation}{hintbases}}}.

\end{fulllineitems}\end{savenotes}

\index{Info Auto (flag)@\spxentry{Info Auto}\spxextra{flag}}\index{Debug Auto (flag)@\spxentry{Debug Auto}\spxextra{flag}}\index{Info Trivial (flag)@\spxentry{Info Trivial}\spxextra{flag}}\index{Debug Trivial (flag)@\spxentry{Debug Trivial}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:flag.Info-Auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Info~Auto}}}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:flag.Debug-Auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~Auto}}}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:flag.Info-Trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Info~Trivial}}}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:flag.Debug-Trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~Trivial}}}}
\sphinxAtStartPar
These {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flags}}}} enable printing of informative or debug information for
the {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} and {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}} tactics.

\end{fulllineitems}\end{savenotes}

\index{eauto (tactic)@\spxentry{eauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eauto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Generalizes {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}. While {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} does not try
resolution hints which would leave existential variables in the goal,
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} does try them (informally speaking, it internally uses a tactic
close to {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple eapply}}}}} instead of a tactic close to {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple apply}}}}}
in the case of {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}). As a consequence, {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}}
can solve such a goal:

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Hint} \PYG{k+kn}{Resolve} \PYG{n}{ex\PYGZus{}intro} \PYG{o}{:} \PYG{n}{core}\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{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n}

\PYG{k}{eauto}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ex\_intro}} is declared as a hint so the proof succeeds.
\end{sphinxadmonition}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The hints databases for auto and eauto}}}}


\index{info\_eauto (tactic)@\spxentry{info\_eauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.info_eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{info\_eauto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
The various options for {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.info_eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{info\_eauto}}}}} are the same as for {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.info_auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{info\_auto}}}}}.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} also obeys the following flags:
\index{Info Eauto (flag)@\spxentry{Info Eauto}\spxextra{flag}}\index{Debug Eauto (flag)@\spxentry{Debug Eauto}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:flag.Info-Eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Info~Eauto}}}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:flag.Debug-Eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~Eauto}}}}
\end{fulllineitems}\end{savenotes}

\index{debug eauto (tactic)@\spxentry{debug eauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.debug-eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{debug~eauto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Behaves like {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} but shows the tactics it tries to solve the goal,
including failing paths.

\end{fulllineitems}\end{savenotes}

\index{bfs eauto (tactic)@\spxentry{bfs eauto}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.bfs-eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{bfs~eauto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-auto_using}]{\sphinxcrossref{\DUrole{hole}{auto\_using}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Like {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}}, but uses a
\sphinxhref{https://en.wikipedia.org/wiki/Breadth-first\_search}{breadth\sphinxhyphen{}first search}%
\begin{footnote}[48]\sphinxAtStartFootnote
\sphinxnolinkurl{https://en.wikipedia.org/wiki/Breadth-first\_search}
%
\end{footnote}.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{autounfold (tactic)@\spxentry{autounfold}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.autounfold}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autounfold~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\DUrole{hole}{hintbases}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Unfolds constants that were declared through a {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Unfold}}}}}
in the given databases.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_occurrences}]{\sphinxcrossref{\DUrole{hole}{simple\_occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
Performs the unfolding in the specified occurrences.

\end{description}

\end{fulllineitems}\end{savenotes}

\index{autorewrite (tactic)@\spxentry{autorewrite}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.autorewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autorewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}~\begin{description}
\item[{\sphinxcode{\sphinxupquote{*}}}] \leavevmode
\sphinxAtStartPar
If present, rewrite all occurrences whose side conditions are solved.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{with \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}] \leavevmode
\sphinxAtStartPar
Specifies the rewriting rule bases to use.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\DUrole{hole}{occurrences}}}}}}}}] \leavevmode
\sphinxAtStartPar
Performs rewriting in the specified occurrences.  Note: the \sphinxcode{\sphinxupquote{at}} clause
is currently not supported.
\index{The ""at"" syntax isn't available yet for the autorewrite tactic (error)@\spxentry{The ""at"" syntax isn't available yet for the autorewrite tactic}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:exn.The-"at"-syntax-isn't-available-yet-for-the-autorewrite-tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~"at"~syntax~isn\textquotesingle{}t~available~yet~for~the~autorewrite~tactic.}}}}
\sphinxAtStartPar
Appears when there is an \sphinxcode{\sphinxupquote{at}} clause on the conclusion.

\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{using {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}] \leavevmode
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} is applied to the main subgoal after each rewriting step.

\end{description}

\sphinxAtStartPar
Applies rewritings according to the rewriting rule bases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.

\sphinxAtStartPar
For each rule base, applies each rewriting to the main subgoal until
it fails. Once all the rules have been processed, if the main subgoal has
changed then the rules
of this base are processed again. If the main subgoal has not changed then
the next base is processed. For the bases, the behavior is very similar to
the processing of the rewriting rules.

\sphinxAtStartPar
The rewriting rule bases are built with the {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Rewrite}}}}}
command.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
This tactic may loop if you build non terminating rewriting systems.
\end{sphinxadmonition}


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Rewrite}}}}} for feeding the database of lemmas used by
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} and {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} for examples showing the use of this tactic.
Also see {\hyperref[\detokenize{addendum/generalized-rewriting:strategies4rewriting}]{\sphinxcrossref{\DUrole{std,std-ref}{Strategies for rewriting}}}}.



\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{Ack} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{Ack0} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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{n}{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{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Global} \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}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\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}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: MacCarthy function}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Lia}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{g} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{g0} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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{n}{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{n}{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Global} \PYG{k+kn}{Hint} \PYG{k+kn}{Rewrite} \PYG{n}{g0} \PYG{n}{g1} \PYG{n}{g2} \PYG{k}{using} \PYG{n}{lia} \PYG{o}{:} \PYG{n}{base1}\PYG{o}{.}
\end{sphinxVerbatim}

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{autorewrite} \PYG{k}{with} \PYG{n}{base1} \PYG{k}{using} \PYG{k+kp}{reflexivity} \PYG{o}{|}\PYG{o}{|} \PYG{k}{simpl}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{autorewrite} \PYG{k}{with} \PYG{n}{base1} \PYG{k}{using} \PYG{k+kp}{reflexivity} \PYG{o}{|}\PYG{o}{|} \PYG{k}{simpl}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{easy (tactic)@\spxentry{easy}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.easy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{easy}}}}
\sphinxAtStartPar
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{proofs/automatic-tactics/auto:coq:tacn.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.symmetry}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{symmetry}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.contradiction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{contradiction}}}}}
and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} of hypothesis.
If this fails, it tries introducing variables and splitting and\sphinxhyphen{}hypotheses,
using the closing tactics afterwards, and splitting the goal using
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.split}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{split}}}}} and recursing.

\sphinxAtStartPar
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}\end{savenotes}

\index{now (tactic)@\spxentry{now}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:tacn.now}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{now~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}
\sphinxAtStartPar
Run \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}}}} followed by {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.easy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{easy}}}}}. This is a notation for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}; easy}}}.

\end{fulllineitems}\end{savenotes}



\subsubsection{The hints databases for auto and eauto}
\label{\detokenize{proofs/automatic-tactics/auto:the-hints-databases-for-auto-and-eauto}}\label{\detokenize{proofs/automatic-tactics/auto:thehintsdatabasesforautoandeauto}}
\sphinxAtStartPar
The hints for {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} and {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} are stored in databases. Each database
maps head symbols to a list of hints.  Use the {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Print-Hint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Hint}}}}} command to view
the database.

\sphinxAtStartPar
Each hint has a cost that is a nonnegative
integer and an optional pattern. Hints with lower costs are tried first.
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} tries a hint when the conclusion of the current goal matches its
pattern or when the hint has no pattern.


\subsubsection{Creating Hint databases}
\label{\detokenize{proofs/automatic-tactics/auto:creating-hint-databases}}
\sphinxAtStartPar
Hint databases can be created with the {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Create-HintDb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Create HintDb}}}}} command or implicitly
by adding a hint to an unknown database.  We recommend you always use {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Create-HintDb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Create HintDb}}}}}
and then imediately use {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Constants}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Constants}}}}} and {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Variables}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Variables}}}}} to make
those settings explicit.

\sphinxAtStartPar
Note that the default transparency
settings differ between these two methods of creation.  Databases created with
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Create-HintDb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Create HintDb}}}}} have the default setting \sphinxcode{\sphinxupquote{Transparent}} for both \sphinxcode{\sphinxupquote{Variables}}
and \sphinxcode{\sphinxupquote{Constants}}, while implicitly created databases have the \sphinxcode{\sphinxupquote{Opaque}} setting.
\index{Create HintDb (command)@\spxentry{Create HintDb}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Create-HintDb}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Create~HintDb~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{discriminated}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Creates a new hint database named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic: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
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{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}
goals), for non\sphinxhyphen{}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}\end{savenotes}



\subsubsection{Creating Hints}
\label{\detokenize{proofs/automatic-tactics/auto:creating-hints}}\label{\detokenize{proofs/automatic-tactics/auto:id1}}\begin{quote}

\sphinxAtStartPar
The various \sphinxcode{\sphinxupquote{Hint}} commands share these elements:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{: \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}} specifies the hint database(s) to add to.
\sphinxstyleemphasis{(Deprecated since version 8.10:} If no {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}s
are given, the hint is added to the \sphinxcode{\sphinxupquote{core}} database.)

\sphinxAtStartPar
Outside of sections, these commands support the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}}, {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}}
and {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} attributes. {\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} is the default.  Inside sections,
only the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute is supported because hints are local to sections.
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} hints are never visible from other modules, even if they
{\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} or {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} the current module.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}} hints are visible from other modules when they {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} the current
module, but not when they only {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} it.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} hints are visible from other modules when they {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} or
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} the current module.

\end{itemize}

\sphinxAtStartPar
\DUrole{versionmodified,added}{New in version 8.14: }The {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Rewrite}}}}} now supports locality attributes like other \sphinxcode{\sphinxupquote{Hint}} commands.

\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.13: }The default value for hint locality will change in a future
release. Hints added outside of sections without an explicit
locality are now deprecated. We recommend using {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}}
where possible.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Hint}} commands are:
\index{Hint Resolve (command)@\spxentry{Hint Resolve}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Resolve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Resolve~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hint_info}]{\sphinxcrossref{\DUrole{hole}{hint\_info}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:id2}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Resolve~\DUrole{alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:grammar-token-hint_info}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hint_info}]{\sphinxcrossref{\DUrole{hole}{hint\_info}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{| \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The first form adds each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} as a hint with the head symbol of the type of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} to the specified hint databases (\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}s). The cost of the hint is the number of
subgoals generated by {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple apply}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} or, if specified, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}. The
associated pattern is inferred from the conclusion of the type of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} or, if specified, the given \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}}}.

\sphinxAtStartPar
If the inferred type
of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} does not start with a product, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is added
to the hint list.  If the type can be reduced to a type starting with a product,
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple apply}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is also added to the hints list.

\sphinxAtStartPar
If the inferred type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} contains a dependent
quantification on a variable which occurs only in the premises 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 only used by
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} / {\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}}, but not by {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}.  A
typical hint that would only be used by {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} is a transitivity
lemma.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}}}}] \leavevmode
\sphinxAtStartPar
The second form adds the left\sphinxhyphen{}to\sphinxhyphen{}right (\sphinxcode{\sphinxupquote{\sphinxhyphen{}>}}) or right\sphinxhyphen{}ot\sphinxhyphen{}left implication (\sphinxcode{\sphinxupquote{<\sphinxhyphen{}}})
of an equivalence as a hint (informally
the hint will be used as, respectively, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}> {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} or
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{<\sphinxhyphen{} {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}},
although as mentioned before, the tactic actually used is a restricted version of
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}).

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
Permits declaring a hint without declaring a new
constant first, but this is not recommended.
\begin{quote}
\index{Declaring arbitrary terms as hints is fragile@\spxentry{Declaring arbitrary terms as hints is fragile}!it is recommended to declare a toplevel constant instead (warning)@\spxentry{it is recommended to declare a toplevel constant instead}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:warn.Declaring-arbitrary-terms-as-hints-is-fragile;-it-is-recommended-to-declare-a-toplevel-constant-instead}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declaring~arbitrary~terms~as~hints~is~fragile;~it~is~recommended~to~declare~a~toplevel~constant~instead}}}}
\end{fulllineitems}\end{savenotes}

\end{quote}

\end{description}
\index{‘qualid’ cannot be used as a hint (error)@\spxentry{‘qualid’ cannot be used as a hint}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:exn._u2018qualid_u2019-cannot-be-used-as-a-hint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~cannot~be~used~as~a~hint}}}}
\sphinxAtStartPar
The head symbol of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is a bound variable
such that this tactic cannot be associated with a constant.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Hint Immediate (command)@\spxentry{Hint Immediate}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Immediate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Immediate~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
For each specified \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, adds the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple apply}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}};}}}
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}}}} {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{]}}}} to the hint list
associated with the head symbol of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}. This
tactic will fail if all the subgoals generated by {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple apply}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} are
not solved immediately by the {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.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}{\sphinxhyphen{}>} \DUrole{name}{n}\DUrole{operator}{=}\DUrole{name}{m}}} that we may want to introduce with 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{proofs/automatic-tactics/auto:coq:tacn.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}}
itself.

\end{fulllineitems}\end{savenotes}

\index{Hint Constructors (command)@\spxentry{Hint Constructors}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Constructors}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Constructors~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
For each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} that is an inductive type, 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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} ...)}}}, {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} will try to apply each constructor.
\index{‘qualid’ is not an inductive type (error)@\spxentry{‘qualid’ is not an inductive type}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:exn._u2018qualid_u2019-is-not-an-inductive-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~not~an~inductive~type}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Hint Unfold (command)@\spxentry{Hint Unfold}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Unfold}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Unfold~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
For each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, adds the tactic {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} to the
hint list that will only be used when the head constant of the goal is {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}.
Its cost is 4.

\end{fulllineitems}\end{savenotes}

\index{Hint Transparent (command)@\spxentry{Hint Transparent}\spxextra{command}}\index{Hint Opaque (command)@\spxentry{Hint Opaque}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Transparent}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Opaque}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~\DUrole{alternative}{\DUrole{alternative-block}{Transparent}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Opaque}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Adds transparency hints to the database, making each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules: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.
\index{Cannot coerce ‘qualid’ to an evaluable reference (error)@\spxentry{Cannot coerce ‘qualid’ to an evaluable reference}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:exn.Cannot-coerce-_u2018qualid_u2019-to-an-evaluable-reference}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~coerce~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~to~an~evaluable~reference.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Hint Constants (command)@\spxentry{Hint Constants}\spxextra{command}}\index{Hint Variables (command)@\spxentry{Hint Variables}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Constants}}\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Variables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~\DUrole{alternative}{\DUrole{alternative-block}{Constants}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Variables}}~\DUrole{alternative}{\DUrole{alternative-block}{Transparent}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Opaque}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Sets the transparency flag for constants or variables for the specified hint
databases.
These flags affect the unification of hints in the database.
We advise using this just after a {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Create-HintDb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Create HintDb}}}}} command.

\end{fulllineitems}\end{savenotes}

\index{Hint Extern (command)@\spxentry{Hint Extern}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Extern}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Extern~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-one_pattern}]{\sphinxcrossref{\DUrole{hole}{one\_pattern}}}}}\DUrole{notation-sup}{?}}~=>~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Extends {\hyperref[\detokenize{proofs/automatic-tactics/auto: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{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} is the cost, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is the pattern
to match and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} is the action to apply.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Use a {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Extern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Extern}}}}} with no pattern to do
pattern matching on hypotheses using \sphinxcode{\sphinxupquote{match goal with}}
inside the tactic.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\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}{:} \PYG{n}{core}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}

\sphinxAtStartPar
One can even use some sub\sphinxhyphen{}patterns of the pattern in
the tactic script. A sub\sphinxhyphen{}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}

\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{n}{list} \PYG{o}{(}\PYG{n}{nat} \PYG{o}{*} \PYG{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{list} \PYG{o}{(}\PYG{n}{nat} \PYG{o}{*} \PYG{n}{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\PYGZus{}auto}\PYG{o}{.}
    \PYG{c}{(*}\PYG{c}{ info auto: }\PYG{c}{*)}
    \PYG{k+kr}{idtac}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{Hint Cut (command)@\spxentry{Hint Cut}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Cut}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Cut~{[}~{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}}~{]}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}}}\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{(hint or instance identifier)}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{(any hint)}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}} | {\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{(disjunction)}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}} {\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{(sequence)}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}} *}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{(Kleene star)}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{emp}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{(empty)}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{eps}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{(epsilon)}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Used to cut the proof search tree according to a regular
expression that matches the paths to be cut.

\sphinxAtStartPar
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 {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Extern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Extern}}}}}s do not have
an associated identifier).
For each hint \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} in the hint database, the current path \sphinxcode{\sphinxupquote{p}}
extended with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
is matched against the current cut expression \sphinxcode{\sphinxupquote{c}} associated with the
hint database.  If the match succeeds the hint is \sphinxstyleemphasis{not} applied.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Hint Cut {\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}}}}} sets the cut expression
to \sphinxcode{\sphinxupquote{\DUrole{notation}{c | {\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hints_regexp}]{\sphinxcrossref{\DUrole{hole}{hints\_regexp}}}}}}}.  The initial cut expression is \sphinxcode{\sphinxupquote{emp}}.

\sphinxAtStartPar
The output of {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Print-HintDb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print HintDb}}}}} shows the cut expression.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The regexp matches the entire path. Most hints will start with a
leading \sphinxcode{\sphinxupquote{( \_* )}} to match the tail of the path. (Note that \sphinxcode{\sphinxupquote{(\_*)}}
misparses since \sphinxcode{\sphinxupquote{*)}} would end a comment.)
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
There is no operator precedence during parsing, one can
check with {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Print-HintDb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print HintDb}}}}} to verify the current cut expression.
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
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}

\end{fulllineitems}\end{savenotes}

\index{Hint Mode (command)@\spxentry{Hint Mode}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Mode}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Mode~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{+}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{!}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\sphinxhyphen{}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Sets an optional mode of use for the identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}. When
proof search has a goal that ends in an application of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} to
arguments \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}} ... {\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}}}, the mode tells if the hints associated with
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} can be applied or not. A mode specification is a list of \sphinxcode{\sphinxupquote{+}},
\sphinxcode{\sphinxupquote{!}} or \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} 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{\sphinxhyphen{}}}) of the identifier. Mode \sphinxcode{\sphinxupquote{\sphinxhyphen{}}} matches any term, mode \sphinxcode{\sphinxupquote{+}} matches a
term if and only if it does not contain existential variables, while mode \sphinxcode{\sphinxupquote{!}}
matches a term if and only if the \sphinxstyleemphasis{head} of the term is not an existential variable.
The head of a term is understood here as the applicative head, recursively,
ignoring casts.

\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Mode}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Mode}}}}} is especially useful for typeclasses, when one does not want
to support default instances and wants to 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{!}} allowing existentials to appear in the index but not at its head.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
\sphinxAtStartPar
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.

\item {} 
\sphinxAtStartPar
If you want to add hints such as {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Transparent}}}}},
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Cut}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Cut}}}}}, or {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Mode}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Mode}}}}}, for typeclass
resolution, do not forget to put them in the
\sphinxcode{\sphinxupquote{typeclass\_instances}} hint database.

\end{itemize}
\end{sphinxadmonition}
\end{quote}
\index{Hint Rewrite (command)@\spxentry{Hint Rewrite}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}\DUrole{notation-sup}{?}}}}}}~\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{using {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
If specified, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} is applied to the generated subgoals, except for the
main subgoal.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}}}}] \leavevmode
\sphinxAtStartPar
Arrows specify the orientation; left to right (\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}>}}}) or right to left (\sphinxcode{\sphinxupquote{\DUrole{notation}{<\sphinxhyphen{}}}}).
If no arrow is given, the default orientation is left to right (\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}>}}}).

\end{description}

\sphinxAtStartPar
Adds the terms \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{+}}}}} (their types must be
equalities) to the rewriting bases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}}.
Note that the rewriting bases are distinct from the {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}
hint bases and that {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} does not take them into account.
\index{Print Rewrite HintDb (command)@\spxentry{Print Rewrite HintDb}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Print-Rewrite-HintDb}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Rewrite~HintDb~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This command displays all rewrite hints contained in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{Remove Hints (command)@\spxentry{Remove Hints}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Remove-Hints}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Remove~Hints~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Removes the hints associated with the \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}} in databases
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.  Note: hints created with {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Extern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Extern}}}}} currently
can't be removed.  The best workaround for this is to make the hints
non global and carefully select which modules you import.

\end{fulllineitems}\end{savenotes}

\index{Print Hint (command)@\spxentry{Print Hint}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Print-Hint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Hint~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{*}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}\DUrole{notation-sup}{?}}}}}}~\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{*}}}}] \leavevmode
\sphinxAtStartPar
Display all declared hints.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}}] \leavevmode
\sphinxAtStartPar
Display all hints associated with the head symbol \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}}.

\end{description}

\sphinxAtStartPar
Displays tactics from the hints list.  The default is to show hints that
apply to the conclusion of the current goal.  The other forms with \sphinxcode{\sphinxupquote{\DUrole{notation}{*}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\DUrole{hole}{reference}}}}}}} can be used even if no proof is open.

\sphinxAtStartPar
Each hint has a cost that is a nonnegative
integer and an optional pattern. The hints with lower cost are tried first.

\end{fulllineitems}\end{savenotes}

\index{Print HintDb (command)@\spxentry{Print HintDb}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Print-HintDb}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~HintDb~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This command displays all hints from database \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}\end{savenotes}



\subsubsection{Hint databases defined in the Coq standard library}
\label{\detokenize{proofs/automatic-tactics/auto:hint-databases-defined-in-the-coq-standard-library}}
\sphinxAtStartPar
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
\sphinxAtStartPar
This special database is automatically used by \sphinxcode{\sphinxupquote{auto}}, except when
pseudo\sphinxhyphen{}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
\sphinxAtStartPar
This database contains all lemmas about Peano’s arithmetic proved in the
directories Init and Arith.

\item[{zarith}] \leavevmode
\sphinxAtStartPar
contains lemmas about binary signed integers from the
directories theories/ZArith. The database also contains
high\sphinxhyphen{}cost hints that call {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} on equations and
inequalities in \sphinxcode{\sphinxupquote{nat}} or \sphinxcode{\sphinxupquote{Z}}.

\item[{bool}] \leavevmode
\sphinxAtStartPar
contains lemmas about booleans, mostly from directory theories/Bool.

\item[{datatypes}] \leavevmode
\sphinxAtStartPar
is for lemmas about lists, streams and so on that are mainly proved
in the Lists subdirectory.

\item[{sets}] \leavevmode
\sphinxAtStartPar
contains lemmas about sets and relations from the directories Sets and
Relations.

\item[{typeclass\_instances}] \leavevmode
\sphinxAtStartPar
contains all the typeclass instances declared in the
environment, including those used for \sphinxcode{\sphinxupquote{setoid\_rewrite}},
from the Classes directory.

\item[{fset}] \leavevmode
\sphinxAtStartPar
internal database for the implementation of the \sphinxcode{\sphinxupquote{FSets}} library.

\item[{ordered\_type}] \leavevmode
\sphinxAtStartPar
lemmas about ordered types (as defined in the legacy \sphinxcode{\sphinxupquote{OrderedType}} module),
mainly used in the \sphinxcode{\sphinxupquote{FSets}} and \sphinxcode{\sphinxupquote{FMaps}} libraries.

\end{description}\end{quote}

\sphinxAtStartPar
You are advised not to put your own hints in the core database, but
use one or several databases specific to your development.


\subsubsection{Hint locality}
\label{\detokenize{proofs/automatic-tactics/auto:hint-locality}}
\sphinxAtStartPar
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 required (using e.g. \sphinxcode{\sphinxupquote{Require A.}}).

\sphinxAtStartPar
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{proofs/automatic-tactics/auto: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).

\sphinxAtStartPar
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{proofs/automatic-tactics/auto:coq:opt.Loose-Hint-Behavior}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Loose Hint Behavior}}}}}
option which accepts three flags allowing for a fine\sphinxhyphen{}grained handling of
non\sphinxhyphen{}imported hints.
\index{Loose Hint Behavior (option)@\spxentry{Loose Hint Behavior}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:opt.Loose-Hint-Behavior}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Loose~Hint~Behavior~\DUrole{alternative}{\DUrole{alternative-block}{"Lax"}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{"Warn"}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{"Strict"}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} accepts three values, which control the behavior of hints w.r.t.
{\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}}:
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Lax": this is the default, and corresponds to the historical behavior,
that is, hints defined outside of a section have a global scope.

\item {} 
\sphinxAtStartPar
"Warn": outputs a warning when a non\sphinxhyphen{}imported hint is used. Note that this
is an over\sphinxhyphen{}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 {} 
\sphinxAtStartPar
"Strict": changes the behavior of an unloaded hint to a immediate fail
tactic, allowing to emulate an import\sphinxhyphen{}scoped hint mechanism.

\end{itemize}

\end{fulllineitems}\end{savenotes}



\subsubsection{Setting implicit automation tactics}
\label{\detokenize{proofs/automatic-tactics/auto:setting-implicit-automation-tactics}}\label{\detokenize{proofs/automatic-tactics/auto:tactics-implicit-automation}}\index{Proof with (command)@\spxentry{Proof with}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proofs/automatic-tactics/auto:coq:cmd.Proof-with}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~with~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:grammar-token-section_var_expr}]{\sphinxcrossref{\DUrole{hole}{section\_var\_expr}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Starts a proof in which {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} is applied to the active goals
after each tactic that ends with \sphinxcode{\sphinxupquote{...}} instead of the usual single period.
"\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}...}}}" is equivalent to "\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}}; {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}.}}}".


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}} in {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Entering and exiting proof mode}}}}.



\end{fulllineitems}\end{savenotes}



\subsection{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
\sphinxAtStartPar
Matthieu Sozeau

\end{description}\end{quote}

\sphinxAtStartPar
This chapter presents the extension of several equality related
tactics to work over user\sphinxhyphen{}defined structures (called setoids) that are
equipped with ad\sphinxhyphen{}hoc equivalence relations meant to behave as
equalities. Actually, the tactics have also been generalized to
relations weaker than equivalences (e.g. rewriting systems). The
toolbox also extends the automatic rewriting capabilities of the
system, allowing the specification of custom strategies for rewriting.

\sphinxAtStartPar
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\sphinxhyphen{}in replacement for the old one
%
\begin{footnote}[49]\sphinxAtStartFootnote
Nicolas Tabareau helped with the gluing.
%
\end{footnote}, hence most of the documentation still applies.

\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
User\sphinxhyphen{}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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
First\sphinxhyphen{}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\sphinxhyphen{}order morphisms are also allowed.

\item {} 
\sphinxAtStartPar
Performance. The implementation is based on a depth\sphinxhyphen{}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}


\subsubsection{Introduction to generalized rewriting}
\label{\detokenize{addendum/generalized-rewriting:introduction-to-generalized-rewriting}}

\paragraph{Relations and morphisms}
\label{\detokenize{addendum/generalized-rewriting:relations-and-morphisms}}
\sphinxAtStartPar
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}

\sphinxAtStartPar
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 \sphinxhyphen{}> list A \sphinxhyphen{}> Prop.}}
\end{sphinxadmonition}

\sphinxAtStartPar
An \sphinxstyleemphasis{instance} of a parametric relation \sphinxcode{\sphinxupquote{R}} with n parameters is any term
\sphinxcode{\sphinxupquote{(R t1 ... tn)}}.

\sphinxAtStartPar
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)}

\sphinxAtStartPar
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 \sphinxhyphen{}> 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}

\sphinxAtStartPar
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 \sphinxhyphen{}> 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 ++>, 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.

\sphinxAtStartPar
The previous definitions are extended straightforwardly to n\sphinxhyphen{}ary
morphisms, that are required to be simultaneously monotone on every
argument.

\sphinxAtStartPar
Morphisms can also be contravariant in one or more of their arguments.
A morphism is contravariant on an argument associated with 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{\sphinxhyphen{}\sphinxhyphen{}>}}
is used in signatures for contravariant morphisms.

\sphinxAtStartPar
Functions having arguments related by symmetric relations instances
are both covariant and contravariant in those arguments. The special
arrow \sphinxcode{\sphinxupquote{==>}} is used in signatures for morphisms that are both
covariant and contravariant.

\sphinxAtStartPar
An instance of a parametric morphism \(f\) with \(n\)
parameters is any term \(f \, t_1 \ldots t_n\).

\begin{sphinxadmonition}{note}{Example: Morphisms}

\sphinxAtStartPar
Continuing the previous example, let \sphinxcode{\sphinxupquote{union: forall (A : Type), list A \sphinxhyphen{}> list A \sphinxhyphen{}> list A}}
perform the union of two sets by appending one list to the other. \sphinxcode{\sphinxupquote{union}} is a binary
morphism parametric over \sphinxcode{\sphinxupquote{A}} that respects the relation instance
\sphinxcode{\sphinxupquote{(set\_eq A)}}. The latter condition is proved by showing:

\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{n}{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}

\sphinxAtStartPar
The signature of the function \sphinxcode{\sphinxupquote{union A}} is \sphinxcode{\sphinxupquote{set\_eq A ==> set\_eq A ==> set\_eq A}}
for all \sphinxcode{\sphinxupquote{A}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: Contravariant morphisms}

\sphinxAtStartPar
The division function \sphinxcode{\sphinxupquote{Rdiv : R \sphinxhyphen{}> R \sphinxhyphen{}> R}} is a morphism of signature
\sphinxcode{\sphinxupquote{le ++> le \sphinxhyphen{}\sphinxhyphen{}> 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}

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}

\sphinxAtStartPar
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}


\paragraph{Adding new relations and morphisms}
\label{\detokenize{addendum/generalized-rewriting:adding-new-relations-and-morphisms}}\index{Add Parametric Relation (command)@\spxentry{Add Parametric Relation}\spxextra{command}}

\begin{savenotes}\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~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{A}}$}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{Aeq}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{reflexivity~proved~by~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{symmetry~proved~by~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{transitivity~proved~by~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Declares a parametric relation of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{A}}$}}}}}}}, which is a \sphinxcode{\sphinxupquote{Type}}, say \sphinxcode{\sphinxupquote{T}}, with
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{Aeq}}$}}}}}}}, which is a relation on \sphinxcode{\sphinxupquote{T}}, i.e. of type \sphinxcode{\sphinxupquote{(T \sphinxhyphen{}> T \sphinxhyphen{}> Prop)}}.
Thus, if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{A}}$}}}}}}} is
\sphinxcode{\sphinxupquote{\DUrole{notation}{A: forall α$_{\text{1}}$ … α$_{\text{n}}$, Type}}} then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{Aeq}}$}}}}}}} is
\sphinxcode{\sphinxupquote{\DUrole{notation}{Aeq: forall α$_{\text{1}}$ … α$_{\text{n}}$, (A α$_{\text{1}}$ … α$_{\text{n}}$) \sphinxhyphen{}> (A α$_{\text{1}}$ … α$_{\text{n}}$) \sphinxhyphen{}> Prop}}},
or equivalently, \sphinxcode{\sphinxupquote{\DUrole{notation}{Aeq: forall α$_{\text{1}}$ … α$_{\text{n}}$, relation (A α$_{\text{1}}$ … α$_{\text{n}}$)}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{A}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{Aeq}}$}}}}}}} must be typeable under the context
{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}}s.  In practice, the {\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}}s usually correspond to the \sphinxcode{\sphinxupquote{\DUrole{notation}{α}}}s

\sphinxAtStartPar
The final {\hyperref[\detokenize{language/core/basic: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.

\sphinxAtStartPar
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).

\sphinxAtStartPar
To use this command, you need to first import the module \sphinxcode{\sphinxupquote{Setoid}} using
the command \sphinxcode{\sphinxupquote{Require Import Setoid}}.

\end{fulllineitems}\end{savenotes}

\index{Add Relation (command)@\spxentry{Add Relation}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.Add-Relation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Relation~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{reflexivity~proved~by~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{symmetry~proved~by~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{transitivity~proved~by~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
If the carrier and relations are not parametric, use this command
instead, whose syntax is the same except there is no local context.

\sphinxAtStartPar
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{name,builtin,pseudo}{…} \DUrole{name}{tn}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{Aeq} \DUrole{name}{t}\DUrole{name,builtin,pseudo}{′} \DUrole{literal,number,integer}{1} \DUrole{name,builtin,pseudo}{…} \DUrole{name}{t}\DUrole{name,builtin,pseudo}{′} \DUrole{name}{n}\DUrole{operator}{)}}}.
Each proof may refer to the introduced variables as well.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example: Parametric relation}

\sphinxAtStartPar
For Leibniz equality, we may declare:

\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}

\sphinxAtStartPar
Some tactics ({\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.symmetry}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{symmetry}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.transitivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{transitivity}}}}}) work only on
relations that respect the expected properties. The remaining tactics
({\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} and derived tactics such as {\hyperref[\detokenize{proofs/automatic-tactics/auto: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 (command)@\spxentry{Add Parametric Morphism}\spxextra{command}}

\begin{savenotes}\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~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~with~signature~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Declares a parametric morphism \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} of
signature \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.  The final identifier {\hyperref[\detokenize{language/core/basic: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\sphinxhyphen{}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 the function denoted by the first
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} respects the relations identified from the signature.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
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.

\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}

\sphinxAtStartPar
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:

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

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

\sphinxAtStartPar
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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{S} \PYG{o}{:} \PYG{k}{set} \PYG{n}{nat}\PYG{o}{)}\PYG{o}{,}
  \PYG{n}{eq\PYGZus{}set} \PYG{o}{(}\PYG{n}{union} \PYG{o}{(}\PYG{n}{union} \PYG{n}{S} \PYG{o}{(}\PYG{n}{empty} \PYG{n}{nat}\PYG{o}{)}\PYG{o}{)} \PYG{n}{S}\PYG{o}{)} \PYG{o}{(}\PYG{n}{union} \PYG{n}{S} \PYG{n}{S}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\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}

\sphinxAtStartPar
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:\sphinxcode{\sphinxupquote{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}


\paragraph{Rewriting and non reflexive relations}
\label{\detokenize{addendum/generalized-rewriting:rewriting-and-non-reflexive-relations}}
\sphinxAtStartPar
To replace only one argument of an n\sphinxhyphen{}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}

\sphinxAtStartPar
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}

\sphinxAtStartPar
When the relations associated with some arguments are not reflexive, the
tactic cannot automatically prove the reflexivity goals, that are left
to the user.

\sphinxAtStartPar
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}

\sphinxAtStartPar
Let \sphinxcode{\sphinxupquote{eqO}} be \sphinxcode{\sphinxupquote{fun x y => x = y /\textbackslash{} x <> 0}} (the
smallest PER over nonzero elements). Division can be declared as a
morphism of signature \sphinxcode{\sphinxupquote{eq ==> eq0 ==> 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 <> 0}}.
\end{sphinxadmonition}


\paragraph{Rewriting and non symmetric relations}
\label{\detokenize{addendum/generalized-rewriting:rewriting-and-non-symmetric-relations}}
\sphinxAtStartPar
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}

\sphinxAtStartPar
Suppose that division over real numbers has been defined as a morphism of signature
\sphinxcode{\sphinxupquote{Z.div : Z.lt ++> Z.lt \sphinxhyphen{}\sphinxhyphen{}> Z.lt}} (i.e. \sphinxcode{\sphinxupquote{Z.div}} is increasing in
its first argument, but decreasing on the second one). Let \sphinxcode{\sphinxupquote{<}}
denote \sphinxcode{\sphinxupquote{Z.lt}}. Under the hypothesis \sphinxcode{\sphinxupquote{H : x < y}} we have
\sphinxcode{\sphinxupquote{k < x / y \sphinxhyphen{}> k < x / x}}, but not \sphinxcode{\sphinxupquote{k < y / x \sphinxhyphen{}> k < x / x}}. Dually,
under the same hypothesis \sphinxcode{\sphinxupquote{k < x / y \sphinxhyphen{}> k < y / y}} holds, but
\sphinxcode{\sphinxupquote{k < y / x \sphinxhyphen{}> k < y / y}} does not. Thus, if the current goal is
\sphinxcode{\sphinxupquote{k < 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 < 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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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}

\sphinxAtStartPar
Let us continue the previous example and let us consider
the goal \sphinxcode{\sphinxupquote{x / (x / x) < 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) < k}} (since \sphinxcode{\sphinxupquote{<}}, as every
transitive relation, is contravariant in its first argument with
respect to the relation itself).
\end{sphinxadmonition}


\paragraph{Rewriting in ambiguous setoid contexts}
\label{\detokenize{addendum/generalized-rewriting:rewriting-in-ambiguous-setoid-contexts}}
\sphinxAtStartPar
One function can respect several different relations and thus it can
be declared as a morphism having multiple signatures.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Union over homogeneous lists can be given all the
following signatures: \sphinxcode{\sphinxupquote{eq ==> eq ==> eq}} (\sphinxcode{\sphinxupquote{eq}} being the
equality over ordered lists) \sphinxcode{\sphinxupquote{set\_eq ==> set\_eq ==> set\_eq}}
(\sphinxcode{\sphinxupquote{set\_eq}} being the equality over unordered lists up to duplicates),
\sphinxcode{\sphinxupquote{multiset\_eq ==> multiset\_eq ==> multiset\_eq}} (\sphinxcode{\sphinxupquote{multiset\_eq}}
being the equality over unordered lists).
\end{sphinxadmonition}

\sphinxAtStartPar
To declare multiple signatures for a morphism, repeat the {\hyperref[\detokenize{addendum/generalized-rewriting:coq:cmd.Add-Morphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add Morphism}}}}}
command.

\sphinxAtStartPar
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.


\subsubsection{Commands and tactics}
\label{\detokenize{addendum/generalized-rewriting:commands-and-tactics}}

\paragraph{First class setoids and morphisms}
\label{\detokenize{addendum/generalized-rewriting:first-class-setoids-and-morphisms}}\label{\detokenize{addendum/generalized-rewriting:id2}}
\sphinxAtStartPar
The implementation is based on a first\sphinxhyphen{}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 these classes are put in a
hint database. For example, the declaration:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Add} \PYG{n}{Parametric} \PYG{k+kn}{Relation} \PYG{o}{(}\PYG{n}{x1} \PYG{o}{:} \PYG{n}{T1}\PYG{o}{)} \PYG{o}{..}\PYG{o}{.} \PYG{o}{(}\PYG{n}{xn} \PYG{o}{:} \PYG{n}{Tn}\PYG{o}{)} \PYG{o}{:} \PYG{o}{(}\PYG{n}{A} \PYG{n}{t1} \PYG{o}{..}\PYG{o}{.} \PYG{n}{tn}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Aeq} \PYG{n}{t}\PYG{n+nb+bp}{′}\PYG{l+m+mi}{1} \PYG{o}{..}\PYG{o}{.} \PYG{n}{t}\PYG{n+nb+bp}{′}\PYG{n}{m}\PYG{o}{)}
  \PYG{o}{[}\PYG{k+kp}{reflexivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{n}{refl}\PYG{o}{]}
  \PYG{o}{[}\PYG{k}{symmetry} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{n}{sym}\PYG{o}{]}
  \PYG{o}{[}\PYG{k}{transitivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{n}{trans}\PYG{o}{]}
  \PYG{k}{as} \PYG{n}{id}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
is equivalent to an instance declaration:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Instance} \PYG{o}{(}\PYG{n}{x1} \PYG{o}{:} \PYG{n}{T1}\PYG{o}{)} \PYG{o}{..}\PYG{o}{.} \PYG{o}{(}\PYG{n}{xn} \PYG{o}{:} \PYG{n}{Tn}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{id} \PYG{o}{:} \PYG{o}{@}\PYG{n}{Equivalence} \PYG{o}{(}\PYG{n}{A} \PYG{n}{t1} \PYG{o}{..}\PYG{o}{.} \PYG{n}{tn}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Aeq} \PYG{n}{t}\PYG{n+nb+bp}{′}\PYG{l+m+mi}{1} \PYG{o}{..}\PYG{o}{.} \PYG{n}{t}\PYG{n+nb+bp}{′}\PYG{n}{m}\PYG{o}{)} \PYG{o}{:=}
  \PYG{o}{[}\PYG{n}{Equivalence\PYGZus{}Reflexive} \PYG{o}{:=} \PYG{n}{refl}\PYG{o}{]}
  \PYG{o}{[}\PYG{n}{Equivalence\PYGZus{}Symmetric} \PYG{o}{:=} \PYG{n}{sym}\PYG{o}{]}
  \PYG{o}{[}\PYG{n}{Equivalence\PYGZus{}Transitive} \PYG{o}{:=} \PYG{n}{trans}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}{Typeclasses}}}} and the theories files in Classes
for further explanations.

\sphinxAtStartPar
One can inform the rewrite tactic about morphisms and relations just
by using the typeclass mechanism to declare them using the {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} and
{\hyperref[\detokenize{language/core/sections:coq:cmd.Context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Context}}}}} 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.

\sphinxAtStartPar
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}

\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}


\paragraph{Tactics enabled on user provided relations}
\label{\detokenize{addendum/generalized-rewriting:tactics-enabled-on-user-provided-relations}}\label{\detokenize{addendum/generalized-rewriting:id3}}
\sphinxAtStartPar
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{proofs/writing-proofs/equality:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.symmetry}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{symmetry}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.transitivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{transitivity}}}}},
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}}, {\hyperref[\detokenize{proofs/writing-proofs/equality: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 (tactic)@\spxentry{setoid\_reflexivity}\spxextra{tactic}}\index{setoid\_symmetry (tactic)@\spxentry{setoid\_symmetry}\spxextra{tactic}}\index{setoid\_transitivity (tactic)@\spxentry{setoid\_transitivity}\spxextra{tactic}}\index{setoid\_rewrite (tactic)@\spxentry{setoid\_rewrite}\spxextra{tactic}}\index{setoid\_replace (tactic)@\spxentry{setoid\_replace}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_reflexivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_reflexivity}}}}\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_symmetry}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_symmetry~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_transitivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_transitivity~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{at~{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewrite_occs}]{\sphinxcrossref{\DUrole{hole}{rewrite\_occs}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{addendum/generalized-rewriting:id4}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}~in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~at~{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewrite_occs}]{\sphinxcrossref{\DUrole{hole}{rewrite\_occs}}}}}}}}\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_replace}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_replace~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~with~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~relation~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-int_or_var}]{\sphinxcrossref{\DUrole{hole}{int\_or\_var}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}\DUrole{notation-sup}{?}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-rewrite_occs}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewrite_occs}]{\sphinxcrossref{\DUrole{hole}{rewrite\_occs}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
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 global 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}\end{savenotes}


\sphinxAtStartPar
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{proofs/automatic-tactics/auto:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} that
are not proofs of Leibniz equalities. In particular it is possible to
exploit {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} to simulate normalization in a term rewriting
system up to user defined equalities.


\paragraph{Printing relations and morphisms}
\label{\detokenize{addendum/generalized-rewriting:printing-relations-and-morphisms}}
\sphinxAtStartPar
Use the {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Print-Instances}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Instances}}}}} command with the class names \sphinxcode{\sphinxupquote{Reflexive}}, \sphinxcode{\sphinxupquote{Symmetric}}
or \sphinxcode{\sphinxupquote{Transitive}} to print registered reflexive, symmetric or transitive relations and
with the class name \sphinxcode{\sphinxupquote{Proper}} to print morphisms.

\sphinxAtStartPar
When rewriting tactics refuse
to replace a term in a context because the latter is not a composition
of morphisms, this command can be useful to understand
what additional morphisms should be registered.


\paragraph{Deprecated syntax and backward incompatibilities}
\label{\detokenize{addendum/generalized-rewriting:deprecated-syntax-and-backward-incompatibilities}}\label{\detokenize{addendum/generalized-rewriting:deprecated-syntax-for-generalized-rewriting}}\index{Add Setoid (command)@\spxentry{Add Setoid}\spxextra{command}}

\begin{savenotes}\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{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{carrier}}$}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{congruence}}$}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{proofs}}$}}}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
This command for declaring setoids and morphisms is also accepted due
to backward compatibility reasons.

\sphinxAtStartPar
Here \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{congruence}}$}}}}}}} is a congruence relation without parameters,
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{carrier}}$}}}}}}} is its carrier and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{proofs}}$}}}}}}} is an object
of type (\sphinxcode{\sphinxupquote{\DUrole{notation}{Setoid\_Theory {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{carrier}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{congruence}}$}}}}}}}) (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}\end{savenotes}

\index{Add Morphism (command)@\spxentry{Add Morphism}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.Add-Morphism}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Morphism~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}\phantomsection\label{\detokenize{addendum/generalized-rewriting:id5}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Morphism~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~with~signature~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
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\sphinxhyphen{}ary
morphisms the hypotheses of the property are permuted; moreover, when
the morphism returns a proposition, the property is now stated using a
bi\sphinxhyphen{}implication in place of a simple implication. In practice, porting
an old development to the new semantics is usually quite simple.

\end{fulllineitems}\end{savenotes}

\index{Declare Morphism (command)@\spxentry{Declare Morphism}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.Declare-Morphism}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Morphism~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~:~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Declares a parameter in a module type that is a morphism.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
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{proofs/writing-proofs/equality:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality: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:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} tactic differs slightly from the old one and
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}.


\subsubsection{Extensions}
\label{\detokenize{addendum/generalized-rewriting:extensions}}

\paragraph{Rewriting under binders}
\label{\detokenize{addendum/generalized-rewriting:rewriting-under-binders}}
\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
Due to compatibility issues, this feature is enabled only
when calling the {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} tactic directly and not {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}.
\end{sphinxadmonition}

\sphinxAtStartPar
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:

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Proof}\PYG{o}{.} \PYG{n}{simpl\PYGZus{}relation}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{pointwise\PYGZus{}relation} \PYG{n}{A} \PYG{n}{iff} \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{n}{all} \PYG{n}{x} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{all} \PYG{n}{y}
\end{sphinxVerbatim}

\sphinxAtStartPar
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).

\sphinxAtStartPar
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 => P x) (fun x => 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 ==> ?) m}}
will be generated for the surrounding morphism \sphinxcode{\sphinxupquote{m}}.

\sphinxAtStartPar
Hence, one can add higher\sphinxhyphen{}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:

\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}

\sphinxAtStartPar
where \sphinxcode{\sphinxupquote{list\_equiv}} implements an equivalence on lists parameterized by
an equivalence on the elements.

\sphinxAtStartPar
Note that when one does rewriting with a lemma under a binder using
{\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.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:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}},
matching is done on each subterm separately and in its local
context, and all matches are rewritten \sphinxstyleemphasis{simultaneously} by
default. The semantics of the previous {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} implementation
can almost be recovered using the \sphinxcode{\sphinxupquote{at 1}} modifier.


\paragraph{Subrelations}
\label{\detokenize{addendum/generalized-rewriting:subrelations}}
\sphinxAtStartPar
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{==>}}, 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 {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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 ==> impl ==> impl) and}} and
\sphinxcode{\sphinxupquote{Proper (iff ==> iff ==> 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}}.

\sphinxAtStartPar
Subrelations are implemented in \sphinxcode{\sphinxupquote{Classes.Morphisms}} and are a prime
example of a mostly user\sphinxhyphen{}space extension of the algorithm.


\paragraph{Constant unfolding}
\label{\detokenize{addendum/generalized-rewriting:constant-unfolding}}
\sphinxAtStartPar
The resolution tactic is based on typeclasses and hence regards user\sphinxhyphen{}defined
{\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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}}}}}.


\subsubsection{Strategies for rewriting}
\label{\detokenize{addendum/generalized-rewriting:strategies-for-rewriting}}\label{\detokenize{addendum/generalized-rewriting:strategies4rewriting}}

\paragraph{Usage}
\label{\detokenize{addendum/generalized-rewriting:usage}}\index{rewrite\_strat (tactic)@\spxentry{rewrite\_strat}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacn.rewrite_strat}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite\_strat~{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Rewrite using \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}} in the conclusion or in the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\index{Nothing to rewrite (error)@\spxentry{Nothing to rewrite}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
The strategy didn't find any matches.

\end{fulllineitems}\end{savenotes}

\index{No progress made (error)@\spxentry{No progress made}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
If the strategy succeeded but made no progress.

\end{fulllineitems}\end{savenotes}

\index{Unable to satisfy the rewriting constraints (error)@\spxentry{Unable to satisfy the rewriting constraints}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
If the strategy succeeded and made progress but the
corresponding rewriting constraints are not satisfied.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
{\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is basically equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite\_strat outermost {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Definitions}
\label{\detokenize{addendum/generalized-rewriting:definitions}}
\sphinxAtStartPar
The generalized rewriting tactic is based on a set of strategies that can be
combined to create custom rewriting procedures. Its set of strategies is based
on the programmable rewriting strategies with generic traversals by Visser et al.
{[}\hyperlink{cite.zebibliography:id33}{LV97}{]} {[}\hyperlink{cite.zebibliography:id34}{VBT98}{]}, which formed the core of
the Stratego transformation language {[}\hyperlink{cite.zebibliography:id35}{Vis01}{]}. Rewriting strategies
are applied using the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite\_strat {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{<\sphinxhyphen{} {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{fail}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{id}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{refl}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{progress {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{try {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} ; {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{choice {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{repeat {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{any {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{subterm {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{subterms {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{innermost {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{outermost {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{bottomup {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{topdown {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{hints {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{terms \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{eval {\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{fold {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{old\_hints {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
lemma, left to right

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{<\sphinxhyphen{} {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
lemma, right to left

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{fail}}}}] \leavevmode
\sphinxAtStartPar
failure

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{id}}}}] \leavevmode
\sphinxAtStartPar
identity

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{refl}}}}] \leavevmode
\sphinxAtStartPar
reflexivity

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{progress {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
progress

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{try {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
try catch

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} ; {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
composition

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{choice {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
left\_biased\_choice

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{repeat {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
one or more

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{any {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
zero or more

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{subterm {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
one subterm

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{subterms {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
all subterms

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{innermost {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
Innermost first.
When there are multiple nested matches in a subterm, the innermost subterm
is rewritten.  For {\hyperref[\detokenize{addendum/generalized-rewriting:rewrite-strat-innermost-outermost}]{\sphinxcrossref{\DUrole{std,std-ref}{example}}}},
rewriting \sphinxcode{\sphinxupquote{\DUrole{notation}{(a + b) + c}}} with Nat.add\_comm gives \sphinxcode{\sphinxupquote{\DUrole{notation}{(b + a) + c}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{outermost {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
Outermost first.
When there are multiple nested matches in a subterm, the outermost subterm
is rewritten.  For {\hyperref[\detokenize{addendum/generalized-rewriting:rewrite-strat-innermost-outermost}]{\sphinxcrossref{\DUrole{std,std-ref}{example}}}},
rewriting \sphinxcode{\sphinxupquote{\DUrole{notation}{(a + b) + c}}} with Nat.add\_comm gives \sphinxcode{\sphinxupquote{\DUrole{notation}{c + (a + b)}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{bottomup {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
bottom\sphinxhyphen{}up

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{topdown {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}}] \leavevmode
\sphinxAtStartPar
top\sphinxhyphen{}down

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{hints {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
apply hints from hint database

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{terms \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}\DUrole{notation-sup}{*}}}}}}] \leavevmode
\sphinxAtStartPar
any of the terms

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{eval {\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}}}}}}] \leavevmode
\sphinxAtStartPar
apply reduction

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{fold {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}] \leavevmode
\sphinxAtStartPar
unify

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{( {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} )}}}}] \leavevmode
\sphinxAtStartPar
to be documented

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{old\_hints {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}] \leavevmode
\sphinxAtStartPar
to be documented

\end{description}

\sphinxAtStartPar
Conceptually, a few of these are defined in terms of the others using a
primitive fixpoint operator \sphinxcode{\sphinxupquote{fix}}, which the tactic doesn't currently support:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{try {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} := choice {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} id}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{any {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} := fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}. try ({\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} ; {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{repeat {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} := {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}; any {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{bottomup {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} := fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}. (choice (progress (subterms {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})) {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}) ; try {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{topdown {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} := fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}. (choice {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} (progress (subterms {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}))) ; try {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{innermost {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} := fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}. (choice (subterm {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}) {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}})}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{outermost {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} := fix {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}. (choice {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}} (subterm {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}))}}}

\end{itemize}

\sphinxAtStartPar
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\sphinxhyphen{}hand\sphinxhyphen{}side of the
lemma with the current subterm and on success rewrite it to the right\sphinxhyphen{}
hand\sphinxhyphen{}side. Composition can be used to continue rewriting on the
current subterm. The \sphinxcode{\sphinxupquote{fail}} strategy always fails while the identity
strategy succeeds without making progress. The reflexivity strategy
succeeds, making progress using a reflexivity proof of rewriting.
\sphinxcode{\sphinxupquote{progress}} tests progress of the argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}} and fails if no
progress was made, while \sphinxcode{\sphinxupquote{try}} always succeeds, catching failures.
\sphinxcode{\sphinxupquote{choice}} is left\sphinxhyphen{}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}}.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{subterm}} and \sphinxcode{\sphinxupquote{subterms}} strategies apply their argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}} to
respectively one or all subterms of the current term under
consideration, left\sphinxhyphen{}to\sphinxhyphen{}right. \sphinxcode{\sphinxupquote{subterm}} stops at the first subterm for
which \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}} made progress. The composite strategies \sphinxcode{\sphinxupquote{innermost}} and \sphinxcode{\sphinxupquote{outermost}}
perform a single innermost or outermost rewrite using their argument
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-rewstrategy}]{\sphinxcrossref{\DUrole{hole}{rewstrategy}}}}}}}. 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.

\sphinxAtStartPar
Hint databases created for {\hyperref[\detokenize{proofs/automatic-tactics/auto: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{proofs/writing-proofs/equality:applyingconversionrules}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying conversion rules}}}}) and succeeds
if it reduces the subterm under consideration. The \sphinxcode{\sphinxupquote{fold}} strategy takes
a {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and tries to \sphinxstyleemphasis{unify} it to the current subterm, converting it to {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
on success. It is stronger than the tactic \sphinxcode{\sphinxupquote{fold}}.

\phantomsection\label{\detokenize{addendum/generalized-rewriting:rewrite-strat-innermost-outermost}}
\begin{sphinxadmonition}{note}{Example: \sphinxstyleliteralintitle{\sphinxupquote{innermost}} and \sphinxstyleliteralintitle{\sphinxupquote{outermost}}}

\sphinxAtStartPar
The type of \sphinxcode{\sphinxupquote{Nat.add\_comm}} is \sphinxcode{\sphinxupquote{forall n m : nat, n + m = m + n}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Arith}\PYG{o}{.}\PYG{n}{Arith}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{ring\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Parentheses}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{n}{c}\PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{n}{c} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{b}\PYG{o}{)} \PYG{o}{+} \PYG{n}{c}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{n}{rewrite\PYGZus{}strat} \PYG{n}{innermost} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}comm}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{o}{(}\PYG{n}{b} \PYG{o}{+} \PYG{n}{a}\PYG{o}{)} \PYG{o}{+} \PYG{n}{c}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

\sphinxAtStartPar
Using \sphinxcode{\sphinxupquote{\DUrole{notation}{outermost}}} instead gives this result:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{rewrite\PYGZus{}strat} \PYG{n}{outermost} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}comm}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{n}{c} \PYG{o}{+} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{b}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\section{Creating new tactics}
\label{\detokenize{proofs/creating-tactics/index:creating-new-tactics}}\label{\detokenize{proofs/creating-tactics/index:writing-tactics}}\label{\detokenize{proofs/creating-tactics/index::doc}}
\sphinxAtStartPar
The languages presented in this chapter allow one to build complex
tactics by combining existing ones with constructs such as
conditionals and looping.  While {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac}}}} was initially
thought of as a language for doing some basic combinations, it has
been used successfully to build highly complex tactics as well, but
this has also highlighted its limits and fragility.  The experimental
language {\hyperref[\detokenize{proof-engine/ltac2:ltac2}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac2}}}} is a typed and more principled variant
which is more adapted to building complex tactics.

\sphinxAtStartPar
There are other solutions beyond these two tactic languages to write
new tactics:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxhref{https://github.com/Mtac2/Mtac2}{Mtac2}%
\begin{footnote}[50]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/Mtac2/Mtac2}
%
\end{footnote} is an external plugin
which provides another typed tactic language.  While Ltac2 belongs
to the ML language family, Mtac2 reuses the language of Coq itself
as the language to build Coq tactics.

\item {} 
\sphinxAtStartPar
The most traditional way of building new complex tactics is to write
a Coq plugin in OCaml.  Beware that this also requires much more
effort and commitment.  A tutorial for writing Coq plugins is
available in the Coq repository in \sphinxhref{https://github.com/coq/coq/tree/master/doc/plugin\_tutorial}{doc/plugin\_tutorial}%
\begin{footnote}[51]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/tree/master/doc/plugin\_tutorial}
%
\end{footnote}.

\end{itemize}


\subsection{Ltac}
\label{\detokenize{proof-engine/ltac:ltac}}\label{\detokenize{proof-engine/ltac:id1}}\label{\detokenize{proof-engine/ltac::doc}}
\sphinxAtStartPar
This chapter documents the tactic language \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$.

\sphinxAtStartPar
We start by giving the syntax followed by the informal
semantics. To learn more about the language and
especially about its foundations, please refer to {[}\hyperlink{cite.zebibliography:id18}{Del00}{]}.
(Note the examples in the paper won't work as\sphinxhyphen{}is; Coq has evolved
since the paper was written.)

\begin{sphinxadmonition}{note}{Example: Basic tactic macros}

\sphinxAtStartPar
Here are some examples of simple tactic macros you can create with \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{reduce\PYGZus{}and\PYGZus{}try\PYGZus{}to\PYGZus{}solve} \PYG{o}{:=} \PYG{k}{simpl}\PYG{o}{;} \PYG{k}{intros}\PYG{o}{;} \PYG{k}{auto}\PYG{o}{.}

\PYG{k+kn}{Ltac} \PYG{n}{destruct\PYGZus{}bool\PYGZus{}and\PYGZus{}rewrite} \PYG{n}{b} \PYG{n}{H1} \PYG{n}{H2} \PYG{o}{:=}
  \PYG{k}{destruct} \PYG{n}{b}\PYG{o}{;} \PYG{o}{[} \PYG{k}{rewrite} \PYG{n}{H1}\PYG{o}{;} \PYG{k}{eauto} \PYG{o}{|} \PYG{k}{rewrite} \PYG{n}{H2}\PYG{o}{;} \PYG{k}{eauto} \PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
See Section {\hyperref[\detokenize{proof-engine/ltac:ltac-examples}]{\sphinxcrossref{\DUrole{std,std-ref}{Examples of using Ltac}}}} for more advanced examples.
\end{sphinxadmonition}


\subsubsection{Syntax}
\label{\detokenize{proof-engine/ltac:syntax}}\label{\detokenize{proof-engine/ltac:ltac-syntax}}
\sphinxAtStartPar
The syntax of the tactic language is given below.

\sphinxAtStartPar
The main entry of the grammar is \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}, which is used in proof mode
as well as to define new tactics with the {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Ltac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac}}}}} command.

\sphinxAtStartPar
The grammar uses multiple \sphinxcode{\sphinxupquote{\DUrole{notation}{ltac\_expr*}}} nonterminals to express how subexpressions
are grouped when they're not fully parenthesized.  For example, in many programming
languages, \sphinxcode{\sphinxupquote{a*b+c}} is interpreted as \sphinxcode{\sphinxupquote{(a*b)+c}} because \sphinxcode{\sphinxupquote{*}} has
higher precedence than \sphinxcode{\sphinxupquote{+}}.  Usually \sphinxcode{\sphinxupquote{a/b/c}} is given the \DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/ltac:term-left-associative}}left associative}
interpretation \sphinxcode{\sphinxupquote{(a/b)/c}} rather than the \DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/ltac:term-right-associative}}right associative} interpretation
\sphinxcode{\sphinxupquote{a/(b/c)}}.

\sphinxAtStartPar
In Coq, the expression \sphinxcode{\sphinxupquote{\DUrole{notation}{try repeat {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}} || {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{2}}$}}}}; {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{3}}$}}}}; {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{4}}$}}}}}}}
is interpreted as \sphinxcode{\sphinxupquote{\DUrole{notation}{(try (repeat ({\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}} || {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{2}}$}}}})); {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{3}}$}}}}); {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{4}}$}}}}}}}
because \sphinxcode{\sphinxupquote{||}} is part of {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr2}}}}}, which has higher precedence than
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.try}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{try}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.repeat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{repeat}}}}} (at the level of {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}}), which
in turn have higher precedence than \sphinxcode{\sphinxupquote{;}}, which is part of {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr4}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr4}}}}}.
(A \sphinxstyleemphasis{lower} number in the nonterminal name means \sphinxstyleemphasis{higher} precedence in this grammar.)

\sphinxAtStartPar
The constructs in {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} are {\hyperref[\detokenize{proof-engine/ltac:term-left-associative}]{\sphinxtermref{\DUrole{xref,std,std-term}{left associative}}}}.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-ltac_expr}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr4}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr4}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\DUrole{hole}{binder\_tactic}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-ltac_expr4}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr4}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr4}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}} ; \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\DUrole{hole}{binder\_tactic}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}} ; {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-for_each_goal}]{\sphinxcrossref{\DUrole{hole}{for\_each\_goal}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\DUrole{hole}{l3\_tactic}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}} + \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\DUrole{hole}{binder\_tactic}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}} || \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\DUrole{hole}{binder\_tactic}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-l2_tactic}]{\sphinxcrossref{\DUrole{hole}{l2\_tactic}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_value}]{\sphinxcrossref{\DUrole{hole}{tactic\_value}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_arg}]{\sphinxcrossref{\DUrole{hole}{tactic\_arg}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-l1_tactic}]{\sphinxcrossref{\DUrole{hole}{l1\_tactic}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr0}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-tactic_value}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_value}]{\sphinxcrossref{\DUrole{hole}{tactic\_value}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-value_tactic}]{\sphinxcrossref{\DUrole{hole}{value\_tactic}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-syn_value}]{\sphinxcrossref{\DUrole{hole}{syn\_value}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-tactic_arg}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_arg}]{\sphinxcrossref{\DUrole{hole}{tactic\_arg}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_value}]{\sphinxcrossref{\DUrole{hole}{tactic\_value}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{()}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-ltac_expr0}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr0}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr0}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[}> {\hyperref[\detokenize{proof-engine/ltac:grammar-token-for_each_goal}]{\sphinxcrossref{\DUrole{hole}{for\_each\_goal}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_atom}]{\sphinxcrossref{\DUrole{hole}{tactic\_atom}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-tactic_atom}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_atom}]{\sphinxcrossref{\DUrole{hole}{tactic\_atom}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{()}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Tactics described in other chapters of the documentation are \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-simple_tactic}}\sphinxcode{\sphinxupquote{simple\_tactic}}}s,
which only modify the proof state.  \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ provides additional constructs that can generally
be used wherever a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-simple_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_tactic}}}}} can appear, even though they don't modify the proof
state and that syntactically they're at
varying levels in {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}.  For simplicity of presentation, the \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ constructs
are documented as tactics.  Tactics are grouped as follows:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-binder_tactic}}\sphinxcode{\sphinxupquote{binder\_tactic}}}s are: {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fun}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fun}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let}}}}}

\item {} 
\sphinxAtStartPar
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-l3_tactic}}\sphinxcode{\sphinxupquote{l3\_tactic}}}s include \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ tactics: {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.try}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{try}}}}},
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.do}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{do}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.repeat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{repeat}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.timeout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{timeout}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.time}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{time}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.progress}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{progress}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}},
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.exactly_once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exactly\_once}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.only}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{only}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}}

\item {} 
\sphinxAtStartPar
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-l2_tactic}}\sphinxcode{\sphinxupquote{l2\_tactic}}}s are: {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.tryif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tryif}}}}}

\item {} 
\sphinxAtStartPar
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-l1_tactic}}\sphinxcode{\sphinxupquote{l1\_tactic}}}s are the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-simple_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_tactic}}}}}s, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}},
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fail}}}}} and
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.gfail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gfail}}}}} as well as {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}} and their \sphinxcode{\sphinxupquote{\DUrole{notation}{lazymatch}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{multimatch}}} variants.

\item {} 
\sphinxAtStartPar
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-value_tactic}}\sphinxcode{\sphinxupquote{value\_tactic}}}s, which return values rather than change the proof state.
They are: {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eval}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.numgoals}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{numgoals}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fresh}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fresh}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.type-of}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type of}}}}}
and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.type_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type\_term}}}}}.

\end{itemize}

\sphinxAtStartPar
The documentation for these \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ constructs mentions which group they belong to.

\sphinxAtStartPar
The difference is only relevant in some compound tactics where
extra parentheses may be needed.  For example, parenthesees are required in
\sphinxcode{\sphinxupquote{\DUrole{notation}{idtac + (once idtac)}}} because {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}, which the
production \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}} ::= {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}} + \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\DUrole{hole}{binder\_tactic}}}}}}}}} doesn't
accept after the \sphinxcode{\sphinxupquote{+}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
\sphinxAtStartPar
The grammar reserves the token \sphinxcode{\sphinxupquote{||}}.

\end{itemize}
\end{sphinxadmonition}


\subsubsection{Semantics}
\label{\detokenize{proof-engine/ltac:semantics}}\label{\detokenize{proof-engine/ltac:ltac-semantics}}

\paragraph{Types of values}
\label{\detokenize{proof-engine/ltac:types-of-values}}
\sphinxAtStartPar
An \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ value can be a tactic, integer, string, unit (written as "\sphinxcode{\sphinxupquote{()}}" ) or syntactic value.
Syntactic values correspond to certain nonterminal symbols in the grammar,
each of which is a distinct type of value.
Most commonly, the value of an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ expression is a tactic that can be executed.

\sphinxAtStartPar
While there are a number of constructs that let you combine multiple tactics into
compound tactics, there are no operations for combining most other types of values.
For example, there's no function to add two integers.  Syntactic values are entered
with the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-syn_value}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{syn\_value}}}}} construct.  Values of all types can be assigned to toplevel
symbols with the {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Ltac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac}}}}} command or to local symbols with the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let}}}}} tactic.
\sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fun}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functions}}}}} can return values of any type.


\paragraph{Syntactic values}
\label{\detokenize{proof-engine/ltac:syntactic-values}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-syn_value}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-syn_value}]{\sphinxcrossref{\DUrole{hole}{syn\_value}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : ( {\hyperref[\detokenize{proof-engine/ltac:grammar-token-nonterminal}]{\sphinxcrossref{\DUrole{hole}{nonterminal}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Provides a way to use the syntax and semantics of a grammar nonterminal as a
value in an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}.  The table below describes the most useful of
these.  You can see the others by running "{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Grammar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Grammar}}}}} \sphinxcode{\sphinxupquote{tactic}}" and
examining the part at the end under "Entry tactic:tactic\_value".
\begin{quote}
\begin{description}
\item[{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}] \leavevmode
\sphinxAtStartPar
name of a grammar nonterminal listed in the table

\item[{\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-nonterminal}}\sphinxcode{\sphinxupquote{nonterminal}}}}] \leavevmode
\sphinxAtStartPar
represents syntax described by {\hyperref[\detokenize{proof-engine/ltac:grammar-token-nonterminal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nonterminal}}}}}.

\end{description}


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
Specified {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Parsed as
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Interpreted as
&\sphinxstyletheadfamily 
\sphinxAtStartPar
as in tactic
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ident}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
&
\sphinxAtStartPar
a user\sphinxhyphen{}specified name
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{string}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}
&
\sphinxAtStartPar
a string
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{integer}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}
&
\sphinxAtStartPar
an integer
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{reference}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}
&
\sphinxAtStartPar
a qualified identifier
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{uconstr}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
&
\sphinxAtStartPar
an untyped term
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{constr}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
&
\sphinxAtStartPar
a term
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ltac}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}
&
\sphinxAtStartPar
a tactic
&\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\end{quote}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{ltac:({\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}})}}} can be used to indicate that the parenthesized item
should be interpreted as a tactic and not as a term.  The constructs can also
be used to pass parameters to tactics written in OCaml.  (While all
of the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-syn_value}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{syn\_value}}}}}s can appear at the beginning of an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}},
the others are not useful because they will not evaluate to tactics.)

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{uconstr:({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} can be used to build untyped terms.
Terms built in \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ are well\sphinxhyphen{}typed by default.  Building large
terms in recursive \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ functions may give very slow behavior because
terms must be fully type checked at each step.  In this case, using
an untyped term may avoid most of the repetitive type checking for the term,
improving performance.

\sphinxAtStartPar
Untyped terms built using \sphinxcode{\sphinxupquote{\DUrole{notation}{uconstr:(…)}}} can be used as arguments to the
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic, for example. 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.


\paragraph{Tactics in terms}
\label{\detokenize{proof-engine/ltac:tactics-in-terms}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-term_ltac}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-term_ltac}]{\sphinxcrossref{\DUrole{hole}{term\_ltac}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ltac : ( {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Allows including an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} within a term.  Semantically,
it's the same as the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-syn_value}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{syn\_value}}}}} for \sphinxcode{\sphinxupquote{ltac}}, but these are
distinct in the grammar.


\paragraph{Substitution}
\label{\detokenize{proof-engine/ltac:substitution}}
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}}s within \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ expressions are used to represent both terms and
\sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ variables.  If the {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} corresponds to
an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ variable or tactic name, \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ substitutes the value before applying
the expression.  Generally it's best to choose distinctive names for \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ variables
that won't clash with term names.  You can use \sphinxcode{\sphinxupquote{\DUrole{notation}{ltac:({\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}})}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}})}}}
to control whether a {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} is interpreted as, respectively, an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$
variable or a term.

\sphinxAtStartPar
Note that values from toplevel symbols, unlike locally\sphinxhyphen{}defined symbols, are
substituted only when they appear at the beginning of an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} or
as a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_arg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic\_arg}}}}}.  Local symbols are also substituted into tactics:

\begin{sphinxadmonition}{note}{Example: Substitution of global and local symbols}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{n} \PYG{o}{:=} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{n}{n} \PYG{k}{is} \PYG{n}{defined}

\PYG{k}{let} \PYG{n}{n2} \PYG{o}{:=} \PYG{n}{n} \PYG{k}{in} \PYG{k+kr}{idtac} \PYG{n}{n2}\PYG{o}{.}
    \PYG{l+m+mi}{1}

\PYG{n}{Fail} \PYG{k+kr}{idtac} \PYG{n}{n}\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{n}{not} \PYG{n}{found}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Sequence: ;}
\label{\detokenize{proof-engine/ltac:sequence}}
\sphinxAtStartPar
A sequence is an expression of the following form:
\index{ltac\sphinxhyphen{}seq (tactic)@\spxentry{ltac\sphinxhyphen{}seq}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.ltac-seq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3$_{\text{1}}$}}}}~;~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3$_{\text{2}}$}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\DUrole{hole}{binder\_tactic}}}}}}}}}}~
\sphinxAtStartPar
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3$_{\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 goals,
possibly producing more goals. Then the right\sphinxhyphen{}hand side 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.

\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
\sphinxAtStartPar
If you want \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{2}}$}}}}; {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{3}}$}}}}}}} to be fully applied to the first
subgoal generated by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}}}}} before applying it to the other
subgoals, then you should write:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}}; {[}> {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{2}}$}}}}; {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{3}}$}}}} .. {]}}}} rather than

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{1}}$}}}}; ({\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{2}}$}}}}; {\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic$_{\text{3}}$}}}})}}}.

\end{itemize}

\end{itemize}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{Local application of tactics: {[}> ... {]}}
\label{\detokenize{proof-engine/ltac:local-application-of-tactics}}\index{{[}> … \textbar{} … \textbar{} … {]} (dispatch) (tactic)@\spxentry{{[}> … \textbar{} … \textbar{} … {]} (dispatch)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn._>-_u2026-|-_u2026-|-_u2026-_-(dispatch)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{[}>~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-for_each_goal}]{\sphinxcrossref{\DUrole{hole}{for\_each\_goal}}}}~{]}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-for_each_goal}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-for_each_goal}]{\sphinxcrossref{\DUrole{hole}{for\_each\_goal}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\DUrole{hole}{goal\_tactics}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\DUrole{hole}{goal\_tactics}}}} |}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}} .. \DUrole{repeat-wrapper}{\DUrole{repeat}{| {\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\DUrole{hole}{goal\_tactics}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-goal_tactics}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\DUrole{hole}{goal\_tactics}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Applies a different \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}} to each of the focused goals.  In the first
form of {\hyperref[\detokenize{proof-engine/ltac:grammar-token-for_each_goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{for\_each\_goal}}}}} (without \sphinxcode{\sphinxupquote{..}}), the construct fails if the number of specified
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}} is not the same as the number of focused goals.  Omitting an
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} leaves the corresponding goal unchanged.

\sphinxAtStartPar
In the second form (with \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}} ..}}}), the left and right {\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{goal\_tactics}}}}}
are applied respectively to a prefix or suffix of the list of focused goals.
The \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}} before the \sphinxcode{\sphinxupquote{..}} is applied to any focused goals in the middle
(possibly none) that are not covered by the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{goal\_tactics}}}}}.  The number of
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{?}}}}} in the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{goal\_tactics}}}}} must be no more than the number of
focused goals.

\sphinxAtStartPar
In particular:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\DUrole{hole}{goal\_tactics}}}} | .. | {\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\DUrole{hole}{goal\_tactics}}}}}}}}] \leavevmode
\sphinxAtStartPar
The goals not covered by the two {\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_tactics}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{goal\_tactics}}}}} are left unchanged.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}> {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} .. {]}}}}}] \leavevmode
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_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
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.swap}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{swap}}}}}, would act as if a single goal is focused.

\end{description}

\sphinxAtStartPar
Note that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}} ; {[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}} {]}}}} is a convenient idiom to
process the goals generated by applying \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{{[} … \textbar{} … \textbar{} … {]} (dispatch) (tactic)@\spxentry{{[} … \textbar{} … \textbar{} … {]} (dispatch)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn._-_u2026-|-_u2026-|-_u2026-_-(dispatch)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}~;~{[}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-for_each_goal}]{\sphinxcrossref{\DUrole{hole}{for\_each\_goal}}}}~{]}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}} ; {[} ... {]}}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}> {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}} ; {[}> ... {]} .. {]}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Goal selectors}
\label{\detokenize{proof-engine/ltac:goal-selectors}}\label{\detokenize{proof-engine/ltac:id3}}
\sphinxAtStartPar
By default, tactic expressions are applied only to the first goal.  Goal
selectors provide a way to apply a tactic expression to another goal or multiple
goals.  (The {\hyperref[\detokenize{proof-engine/tactics:coq:opt.Default-Goal-Selector}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Default Goal Selector}}}}} option can be used to change the default
behavior.)
\index{… : … (goal selector) (tactic)@\spxentry{… : … (goal selector)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn._u2026-:-_u2026-(goal-selector)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \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-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-toplevel_selector}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-toplevel_selector}]{\sphinxcrossref{\DUrole{hole}{toplevel\_selector}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{all}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{!}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{par}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Reorders the goals and applies {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} to the selected goals.  It can
only be used at the top level of a tactic expression; it cannot be used within a
tactic expression.  The selected goals are reordered so they appear after the
lowest\sphinxhyphen{}numbered selected goal, ordered by goal number.  {\hyperref[\detokenize{proof-engine/ltac:reordering-goals-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.  If the selector applies
to a single goal or to all goals, the reordering will not be apparent.  The order of
the goals in the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{selector}}}}} is irrelevant.  (This may not be what you expect;
see \sphinxhref{https://github.com/coq/coq/issues/8481}{\#8481}%
\begin{footnote}[52]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/8481}
%
\end{footnote}.)
\begin{description}
\item[{\sphinxcode{\sphinxupquote{all}}}] \leavevmode
\sphinxAtStartPar
Selects all focused goals.

\item[{\sphinxcode{\sphinxupquote{!}}}] \leavevmode
\sphinxAtStartPar
If exactly one goal is in focus, apply {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} to it.
Otherwise the tactic fails.

\item[{\sphinxcode{\sphinxupquote{par}}}] \leavevmode
\sphinxAtStartPar
Applies \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} to all focused goals in parallel.
The number of workers can be controlled via the command line option
\sphinxcode{\sphinxupquote{\DUrole{notation}{\sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}tac\sphinxhyphen{}j {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} to specify the desired number of workers.
Limitations: \sphinxcode{\sphinxupquote{par:}} only works on goals that don't contain existential
variables.  \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} must either solve the goal completely or do
nothing (i.e. it cannot make some progress).

\end{description}

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Selectors can also be used nested within a tactic expression with the
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.only}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{only}}}}} tactic:
\index{only (tactic)@\spxentry{only}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.only}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{only~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}~:~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-selector}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-range_selector}]{\sphinxcrossref{\DUrole{hole}{range\_selector}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-range_selector}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-range_selector}]{\sphinxcrossref{\DUrole{hole}{range\_selector}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}} \sphinxhyphen{} {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Applies {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}} to the selected goals.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.only}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{only}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-range_selector}]{\sphinxcrossref{\DUrole{hole}{range\_selector}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}] \leavevmode
\sphinxAtStartPar
The selected goals are the union of the specified {\hyperref[\detokenize{proof-engine/ltac:grammar-token-range_selector}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{range\_selector}}}}}s.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
Limits the application of {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}} to the goal previously named {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
by the user (see {\hyperref[\detokenize{language/extensions/evars:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}).

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural$_{\text{1}}$}}}} \sphinxhyphen{} {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural$_{\text{2}}$}}}}}}}}] \leavevmode
\sphinxAtStartPar
Selects the goals \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural$_{\text{1}}$}}}}}}} through \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural$_{\text{2}}$}}}}}}}, inclusive.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}] \leavevmode
\sphinxAtStartPar
Selects a single goal.

\end{description}

\end{fulllineitems}\end{savenotes}

\index{No such goal. (Goal selector) (error)@\spxentry{No such goal. (Goal selector)}\spxextra{error}}

\begin{savenotes}\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{savenotes}

\phantomsection\label{\detokenize{proof-engine/ltac:reordering-goals-ex}}
\begin{sphinxadmonition}{note}{Example: Selector reordering goals}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{l+m+mi}{1}\PYG{o}{=}\PYG{l+m+mi}{0} \PYG{o}{/\PYGZbs{}} \PYG{l+m+mi}{2}\PYG{o}{=}\PYG{l+m+mi}{0} \PYG{o}{/\PYGZbs{}} \PYG{l+m+mi}{3}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kr}{repeat} \PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{0}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{l+m+mi}{1}\PYG{o}{,}\PYG{l+m+mi}{3}\PYG{o}{:} \PYG{k+kr}{idtac}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{0}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Processing multiple goals}
\label{\detokenize{proof-engine/ltac:processing-multiple-goals}}
\sphinxAtStartPar
When presented with multiple focused goals, most \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ constructs process each goal
separately.  They succeed only if there is a success for each goal.  For example:

\begin{sphinxadmonition}{note}{Example: Multiple focused goals}

\sphinxAtStartPar
This tactic fails because there no match for the second goal (\sphinxcode{\sphinxupquote{False}}).

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{2} \PYG{n}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{n}{all}\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}{numgoals =}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{n}\PYG{o}{;}
\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
\PYG{o}{|} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{numgoals} \PYG{o}{=} \PYG{l+m+mi}{2}
    \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}{No} \PYG{n}{matching} \PYG{n}{clauses} \PYG{k}{for} \PYG{k}{match}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Do loop}
\label{\detokenize{proof-engine/ltac:do-loop}}\index{do (tactic)@\spxentry{do}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.do}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{do~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
The do loop repeats a tactic {\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nat\_or\_var}}}}} times:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{v}}, which must be a tactic value. This tactic
value \sphinxcode{\sphinxupquote{v}} is applied {\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nat\_or\_var}}}}} times. If {\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nat\_or\_var}}}}} > 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 {\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nat\_or\_var}}}}}
applications have been completed.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.do}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{do}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Repeat loop}
\label{\detokenize{proof-engine/ltac:repeat-loop}}\index{repeat (tactic)@\spxentry{repeat}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.repeat}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{repeat~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
The repeat loop repeats a tactic until it fails.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_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 {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.repeat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{repeat}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} itself never fails.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.repeat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{repeat}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Catching errors: try}
\label{\detokenize{proof-engine/ltac:catching-errors-try}}
\sphinxAtStartPar
We can catch the tactic errors with:
\index{try (tactic)@\spxentry{try}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.try}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{try~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_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\sphinxhyphen{}raised with its
level decremented.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.try}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{try}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Detecting progress}
\label{\detokenize{proof-engine/ltac:detecting-progress}}
\sphinxAtStartPar
We can check if a tactic made progress with:
\index{progress (tactic)@\spxentry{progress}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.progress}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{progress~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{v}} which must be a tactic value. The tactic value \sphinxcode{\sphinxupquote{v}}
is applied to each focused 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.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.progress}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{progress}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.
\index{Failed to progress (error)@\spxentry{Failed to progress}\spxextra{error}}

\begin{savenotes}\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{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Branching and backtracking}
\label{\detokenize{proof-engine/ltac:branching-and-backtracking}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ provides several \DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/ltac:term-branching}}branching} tactics that permit trying multiple alternative tactics
for a proof step.  For example, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}}, which tries several alternatives and selects the first
that succeeds, or {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.tryif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tryif}}}}}, which tests whether a given tactic would succeed or fail if it was
applied and then, depending on the result, applies one of two alternative tactics.  There
are also looping constructs {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.do}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{do}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.repeat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{repeat}}}}}.  The order in which the subparts
of these tactics are evaluated is generally similar to
structured programming constructs in many languages.

\sphinxAtStartPar
The {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.+-(backtracking-branching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{+}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch goal}}}}} tactics
provide more complex capability.  Rather than applying a single successful
tactic, these tactics generate a series of successful tactic alternatives that are tried sequentially
when subsequent tactics outside these constructs fail.  For example:
\begin{quote}

\begin{sphinxadmonition}{note}{Example: Backtracking}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{n}{multimatch} \PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end} \PYG{o}{;}
\PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \PYG{n}{branch} \PYG{n}{A}
    \PYG{n}{branch} \PYG{l+m+mi}{2}
    \PYG{n}{branch} \PYG{n}{A}
    \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}{Tactic} \PYG{n}{failure}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}

\sphinxAtStartPar
These constructs are evaluated using \DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/ltac:term-backtracking}}backtracking}.  Each  creates a
\DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/ltac:term-backtracking-point}}backtracking point}.  When a subsequent tactic fails, evaluation continues from the nearest
prior backtracking point with the next successful alternative and repeats the tactics after
the backtracking point.  When a backtracking point has
no more successful alternatives, evaluation continues from the next prior backtracking point.
If there are no more prior backtracking points, the overall tactic fails.

\sphinxAtStartPar
Thus, backtracking tactics can have multiple successes.  Non\sphinxhyphen{}backtracking constructs that appear
after a backtracking point are reprocessed after backtracking, as in the example
above, in which the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.ltac-seq}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{;}}}}} construct is reprocessed after backtracking.  When a
backtracking construct is within
a non\sphinxhyphen{}backtracking construct, the latter uses the \DUrole{term-defn}{\phantomsection\label{\detokenize{proof-engine/ltac:term-first-success}}first success}.  Backtracking to
a point within a non\sphinxhyphen{}backtracking construct won't change the branch that was selected by the
non\sphinxhyphen{}backtracking construct.

\sphinxAtStartPar
The {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}} tactic stops further backtracking to backtracking points within that tactic.


\paragraph{Branching with backtracking: +}
\label{\detokenize{proof-engine/ltac:branching-with-backtracking}}
\sphinxAtStartPar
We can branch with backtracking with the following structure:
\index{+ (backtracking branching) (tactic)@\spxentry{+ (backtracking branching)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.+-(backtracking-branching)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}}~+~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\DUrole{hole}{binder\_tactic}}}}}}}}}}
\sphinxAtStartPar
Evaluates and applies \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}}}}} to each focused goal independently.  If it fails
(i.e. there is no initial success), then evaluates and applies the right\sphinxhyphen{}hand side.  If the
right\sphinxhyphen{}hand side fails, the construct fails.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{ltac\_expr1}}} has an initial success and a subsequent tactic (outside the \sphinxcode{\sphinxupquote{+}} construct)
fails, \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ backtracks and selects the next success for \sphinxcode{\sphinxupquote{\DUrole{notation}{ltac\_expr1}}}.  If there are
no more successes, then \sphinxcode{\sphinxupquote{+}} similarly evaluates and applies (and backtracks in) the right\sphinxhyphen{}hand side.
To prevent evaluation of further alternatives after an initial success for a tactic, use {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}} instead.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{+}} is left\sphinxhyphen{}associative.

\sphinxAtStartPar
In all cases, \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{1}}$}}}} + {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{2}}$}}}}); {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{3}}$}}}}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{1}}$}}}}; {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{3}}$}}}}) + ({\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{2}}$}}}}; {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{3}}$}}}})}}}.

\sphinxAtStartPar
Additionally, in most cases, \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{1}}$}}}} + {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{2}}$}}}}) + {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{3}}$}}}}}}} is
equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{1}}$}}}} + ({\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{2}}$}}}} + {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{3}}$}}}})}}}.
Here's an example where the behavior differs slightly:
\begin{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{o}{(}\PYG{n}{fail} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{k+kr}{idtac}\PYG{o}{)} \PYG{o}{+} \PYG{k+kr}{idtac}\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}{Tactic} \PYG{n}{failure}\PYG{o}{.}

\PYG{n}{Fail} \PYG{n}{fail} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{o}{(}\PYG{k+kr}{idtac} \PYG{o}{+} \PYG{k+kr}{idtac}\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{k+kn}{Tactic} \PYG{n}{failure} \PYG{o}{(}\PYG{n}{level} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{quote}

\begin{sphinxadmonition}{note}{Example: Backtracking branching with +}

\sphinxAtStartPar
In the first tactic, \sphinxcode{\sphinxupquote{idtac "2"}} is not executed.  In the second, the subsequent \sphinxcode{\sphinxupquote{fail}} causes
backtracking and the execution of \sphinxcode{\sphinxupquote{idtac "B"}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{+} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{2}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{l+m+mi}{1}

\PYG{n}{assert\PYGZus{}fails} \PYG{o}{(}\PYG{o}{(}\PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{+} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{B}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{A}
    \PYG{n}{B}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{First tactic to succeed}
\label{\detokenize{proof-engine/ltac:first-tactic-to-succeed}}
\sphinxAtStartPar
In some cases backtracking may be too expensive.
\index{first (tactic)@\spxentry{first}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.first}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{first~{[}~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}}~{]}}}}}
\sphinxAtStartPar
For each focused goal, independently apply the first {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} that succeeds.
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}s must evaluate to tactic values.
Failures in tactics after the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}} won't cause backtracking.
(To allow backtracking, use the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.+-(backtracking-branching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{+}}}}}
construct above instead.)

\sphinxAtStartPar
If the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}} contains a tactic that can backtrack, "success" means
the first success of that tactic.  Consider the following:

\begin{sphinxadmonition}{note}{Example: Backtracking inside a non\sphinxhyphen{}backtracking construct}

\sphinxAtStartPar
The {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fail}}}}} doesn't trigger the second {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{assert\PYGZus{}fails} \PYG{o}{(}\PYG{k+kr}{first} \PYG{o}{[} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{|} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{2}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1}
\end{sphinxVerbatim}

\sphinxAtStartPar
This backtracks within \sphinxcode{\sphinxupquote{(idtac "1A" + idtac "1B" + fail)}} but
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}} won't consider the \sphinxcode{\sphinxupquote{idtac "2"}} alternative:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{assert\PYGZus{}fails} \PYG{o}{(}\PYG{k+kr}{first} \PYG{o}{[} \PYG{o}{(}\PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1A}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{+} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{+} \PYG{n}{fail}\PYG{o}{)} \PYG{o}{|} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{2}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1}\PYG{n}{A}
    \PYG{l+m+mi}{1}\PYG{n}{B}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l1_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l1\_tactic}}}}}.
\index{No applicable tactic (error)@\spxentry{No applicable tactic}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}



\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{first~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}
\sphinxAtStartPar
This is an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ alias that gives a primitive access to the first
tactical as an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ definition without going through a parsing rule. It
expects to be given a list of tactics through a {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Tactic-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Tactic Notation}}}}} command,
permitting notations with the following form to be written:

\begin{sphinxadmonition}{note}{Example}

\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{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Solving}
\label{\detokenize{proof-engine/ltac:solving}}
\sphinxAtStartPar
Selects and applies the first tactic that solves each goal (i.e. leaves no subgoal)
in a series of alternative tactics:
\index{solve (tactic)@\spxentry{solve}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.solve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{solve~{[}~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{i}}$}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}}~{]}}}}}
\sphinxAtStartPar
For each current subgoal: evaluates and applies each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} in order
until one is found that solves the subgoal.

\sphinxAtStartPar
If any of the subgoals are not solved, then the overall {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}} fails.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
In {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}s that don't
evaluate to tactic values are ignored.  So {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}} \sphinxcode{\sphinxupquote{{[} () | 1 |}} {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.constructor}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{constructor}}}}} \sphinxcode{\sphinxupquote{{]}}}
is equivalent to {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}} \sphinxcode{\sphinxupquote{{[}}} {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.constructor}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{constructor}}}}} \sphinxcode{\sphinxupquote{{]}}}.
This may make it harder to debug scripts that inadvertently include non\sphinxhyphen{}tactic values.
\end{sphinxadmonition}

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l1_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l1\_tactic}}}}}.


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{solve~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}
\sphinxAtStartPar
This is an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ alias that gives a primitive access to the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}}
tactic. See the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first}}}}} tactic for more information.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{First tactic to make progress: ||}
\label{\detokenize{proof-engine/ltac:first-tactic-to-make-progress}}
\sphinxAtStartPar
Yet another way of branching without backtracking is the following
structure:
\index{\textbar{}\textbar{} (first tactic making progress) (tactic)@\spxentry{\textbar{}\textbar{} (first tactic making progress)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.||-(first-tactic-making-progress)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}}~||~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\DUrole{hole}{binder\_tactic}}}}}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}} || {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}}}} is
equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{first {[} progress {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr1}}}} | {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}} {]}}}}, except that
if it fails, it fails like \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}. \`{}||}}} is left\sphinxhyphen{}associative.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}s that don't evaluate to tactic values are ignored.  See the
note at {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Conditional branching: tryif}
\label{\detokenize{proof-engine/ltac:conditional-branching-tryif}}\index{tryif (tactic)@\spxentry{tryif}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.tryif}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{tryif~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{test}}$}}}}~then~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{then}}$}}}}~else~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2$_{\text{else}}$}}}}}}}}
\sphinxAtStartPar
For each focused goal, independently: Evaluate and apply \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{test}}$}}}}}}}.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{test}}$}}}}}}} succeeds at least once, evaluate and apply \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{then}}$}}}}}}}
to all the subgoals generated by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{test}}$}}}}}}}.  Otherwise, evaluate and apply
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2$_{\text{else}}$}}}}}}} to all the subgoals generated by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{test}}$}}}}}}}.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.tryif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tryif}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l2_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l2\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Soft cut: once}
\label{\detokenize{proof-engine/ltac:soft-cut-once}}
\sphinxAtStartPar
Another way of restricting backtracking is to restrict a tactic to a
single success:
\index{once (tactic)@\spxentry{once}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.once}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{once~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} 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,
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} fails like \sphinxcode{\sphinxupquote{v}}. If \sphinxcode{\sphinxupquote{v}} has at least one success,
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} succeeds once, but cannot produce more successes.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Checking for a single success: exactly\_once}
\label{\detokenize{proof-engine/ltac:checking-for-a-single-success-exactly-once}}
\sphinxAtStartPar
Coq provides an experimental way to check that a tactic has \sphinxstyleemphasis{exactly
one} success:
\index{exactly\_once (tactic)@\spxentry{exactly\_once}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.exactly_once}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exactly\_once~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} 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,
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.exactly_once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exactly\_once}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} fails like \sphinxcode{\sphinxupquote{v}}. If \sphinxcode{\sphinxupquote{v}} has a exactly one success,
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.exactly_once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exactly\_once}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} succeeds like \sphinxcode{\sphinxupquote{v}}. If \sphinxcode{\sphinxupquote{v}} has two or more
successes, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.exactly_once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exactly\_once}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} fails.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.exactly_once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exactly\_once}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The experimental status of this tactic pertains to the fact if \sphinxcode{\sphinxupquote{v}}
has 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 {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.exactly_once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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 (error)@\spxentry{This tactic has more than one success}\spxextra{error}}

\begin{savenotes}\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{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Checking for failure: assert\_fails}
\label{\detokenize{proof-engine/ltac:checking-for-failure-assert-fails}}
\sphinxAtStartPar
Coq defines an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ tactic in \sphinxcode{\sphinxupquote{Init.Tactics}} to check that a tactic \sphinxstyleemphasis{fails}:
\index{assert\_fails (tactic)@\spxentry{assert\_fails}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.assert_fails}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert\_fails~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} fails, the proof state is unchanged and no message is printed.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} unexpectedly has at least one success, the tactic performs
a {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.gfail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gfail}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{0}}}, printing the following message:
\index{Tactic failure: <tactic closure> succeeds (error)@\spxentry{Tactic failure: <tactic closure> succeeds}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.Tactic-failure:-<tactic-closure>-succeeds}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~failure:~<tactic~closure>~succeeds.}}}}
\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_fails}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_fails}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_succeeds}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_succeeds}}}}} work as described when
{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-simple_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_tactic}}}}}.  In some more complex expressions,
they may report an error from within {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}} when they shouldn't.
This is due to the order in which parts of the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}}
are evaluated and executed.  For example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{assert\PYGZus{}fails} \PYG{k}{match} \PYG{n}{True} \PYG{k}{with} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{fail} \PYG{k}{end}\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{n}{assert\PYGZus{}fails} \PYG{k}{match} \PYG{n}{True} \PYG{k}{with} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{fail} \PYG{k}{end}\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}{Error}\PYG{o}{:} \PYG{k+kn}{Tactic} \PYG{n}{failure}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
should not show any message.  The issue is that {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_fails}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_fails}}}}} is an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$\sphinxhyphen{}defined
tactic.  That makes it a function that's processed in the evaluation phase, causing
the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} to find its first success earlier.  One workaround
is to prefix {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr3}}}}} with "\sphinxcode{\sphinxupquote{idtac;}}".

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{assert\PYGZus{}fails} \PYG{o}{(}\PYG{k+kr}{idtac}\PYG{o}{;} \PYG{k}{match} \PYG{n}{True} \PYG{k}{with} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{fail} \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Alternatively, substituting the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} into the definition of {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_fails}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_fails}}}}} works
as expected:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{tryif} \PYG{o}{(}\PYG{n}{once} \PYG{k}{match} \PYG{n}{True} \PYG{k}{with} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{fail} \PYG{k}{end}\PYG{o}{)} \PYG{k}{then} \PYG{n}{gfail} \PYG{l+m+mi}{0} \PYG{c}{(*}\PYG{c}{ tac }\PYG{c}{*)} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{succeeds}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{else} \PYG{k+kr}{idtac}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{Checking for success: assert\_succeeds}
\label{\detokenize{proof-engine/ltac:checking-for-success-assert-succeeds}}
\sphinxAtStartPar
Coq defines an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ tactic in \sphinxcode{\sphinxupquote{Init.Tactics}} to check that a tactic has \sphinxstyleemphasis{at least one}
success:
\index{assert\_succeeds (tactic)@\spxentry{assert\_succeeds}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.assert_succeeds}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert\_succeeds~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} has at least one success, the proof state is unchanged and
no message is printed.  If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} fails, the tactic performs
a {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.gfail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gfail}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{0}}}, printing the following message:
\index{Tactic failure: <tactic closure> fails (error)@\spxentry{Tactic failure: <tactic closure> fails}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.Tactic-failure:-<tactic-closure>-fails}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~failure:~<tactic~closure>~fails.}}}}
\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Print/identity tactic: idtac}
\label{\detokenize{proof-engine/ltac:print-identity-tactic-idtac}}\index{idtac (tactic)@\spxentry{idtac}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.idtac}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{idtac~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
Leaves the proof unchanged and prints the given tokens. {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String}}}}}s
and {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}s are printed
literally. If {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ variable, its contents are printed; if not, it
is an error.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l1_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l1\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Failing}
\label{\detokenize{proof-engine/ltac:failing}}\index{fail (tactic)@\spxentry{fail}\spxextra{tactic}}\index{gfail (tactic)@\spxentry{gfail}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.fail}}\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.gfail}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{fail}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{gfail}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fail}}}}} is the always\sphinxhyphen{}failing tactic: it does not solve any
goal. It is useful for defining other tactics 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.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.gfail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gfail}}}}} fails even when used after \sphinxcode{\sphinxupquote{\DUrole{notation}{;}}} and there are no goals left.
Similarly, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.gfail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gfail}}}}} fails even when used after \sphinxcode{\sphinxupquote{all:}} and there are no
goals left.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fail}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.gfail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gfail}}}}} are {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l1_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l1\_tactic}}}}}s.

\sphinxAtStartPar
See the example for a comparison of the two constructs.

\sphinxAtStartPar
Note that 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 {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{x := H in}}} {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fail}}}}} \sphinxcode{\sphinxupquote{0 x}} will succeed.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}}}}] \leavevmode
\sphinxAtStartPar
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 {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fail}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} is not enclosed in a \sphinxcode{\sphinxupquote{\DUrole{notation}{+}}} construct,
respecting the algebraic identity.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}\DUrole{notation-sup}{*}}}}}}] \leavevmode
\sphinxAtStartPar
The given tokens are used for printing the failure message.  If {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
is an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ variable, its contents are printed; if not, it is an error.

\end{description}
\index{Tactic failure (error)@\spxentry{Tactic failure}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.Tactic-failure}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~failure.}}}}
\end{fulllineitems}\end{savenotes}

\index{Tactic failure (level ‘natural’) (error)@\spxentry{Tactic failure (level ‘natural’)}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.Tactic-failure-(level-_u2018natural_u2019)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~failure~(level~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}).}}}}
\end{fulllineitems}\end{savenotes}

\index{No such goal. (fail) (error)@\spxentry{No such goal. (fail)}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k+kn}{Abort}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{7}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{12}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Proof}\PYG{o}{.} \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{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}


\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k+kn}{Abort}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
    
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{16}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{21}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k}{trivial}\PYG{o}{.} \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{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{all}\PYG{o}{:} \PYG{n}{fail}\PYG{o}{.} \PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}


\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k+kn}{Abort}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{7}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{13}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Proof}\PYG{o}{.} \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{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k+kn}{Abort}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{7}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{22}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Proof}\PYG{o}{.} \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{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k+kn}{Abort}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
    
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{16}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{22}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Proof}\PYG{o}{.} \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{n}{Error}\PYG{o}{:} \PYG{n}{No} \PYG{n}{such} \PYG{n}{goal}\PYG{o}{.}


\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{all}\PYG{o}{:} \PYG{n}{gfail}\PYG{o}{.} \PYG{k+kn}{Abort}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
    
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{16}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{27}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Proof}\PYG{o}{.} \PYG{k}{trivial}\PYG{o}{.} \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}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{Timeout}
\label{\detokenize{proof-engine/ltac:timeout}}
\sphinxAtStartPar
We can force a tactic to stop if it has not finished after a certain
amount of time:
\index{timeout (tactic)@\spxentry{timeout}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.timeout}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{timeout~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} 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{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}}} seconds
if it is still running. In this case the outcome is a failure.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.timeout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{timeout}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
For the moment, timeout is based on elapsed time in seconds,
which is very machine\sphinxhyphen{}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}\end{savenotes}



\paragraph{Timing a tactic}
\label{\detokenize{proof-engine/ltac:timing-a-tactic}}
\sphinxAtStartPar
A tactic execution can be timed:
\index{time (tactic)@\spxentry{time}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.time}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{time~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
evaluates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}} 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\sphinxhyphen{}dependent. The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}
argument is optional. When provided, it is used to identify this particular
occurrence of {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.time}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{time}}}}}.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.time}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{time}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Timing a tactic that evaluates to a term: time\_constr}
\label{\detokenize{proof-engine/ltac:timing-a-tactic-that-evaluates-to-a-term-time-constr}}
\sphinxAtStartPar
Tactic expressions that produce terms can be timed with the experimental
tactic
\index{time\_constr (tactic)@\spxentry{time\_constr}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.time_constr}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{time\_constr~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}
\sphinxAtStartPar
which evaluates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}} ()}}} and displays the time the tactic expression
evaluated, assuming successful evaluation. Time is in seconds and is
machine\sphinxhyphen{}dependent.

\sphinxAtStartPar
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 following internal tactics:

\end{fulllineitems}\end{savenotes}

\index{restart\_timer (tactic)@\spxentry{restart\_timer}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.restart_timer}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{restart\_timer~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Reset a timer

\end{fulllineitems}\end{savenotes}

\index{finish\_timing (tactic)@\spxentry{finish\_timing}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.finish_timing}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{finish\_timing~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~)}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Display an optionally named timer. The parenthesized string argument
is also optional, and determines the label associated with the timer
for printing.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
By copying the definition of {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.time_constr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{time\_constr}}}}} from the standard library,
users can achieve support for a fixed pattern of nesting by passing
different {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} parameters to {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.restart_timer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{restart\_timer}}}}} and
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.finish_timing}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{finish\_timing}}}}} at each level of nesting.

\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{l+m+mi}{001} \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}{goal}
      
      \PYG{n}{n} \PYG{o}{:=} \PYG{l+m+mi}{100} \PYG{o}{:} \PYG{n}{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}


\paragraph{Local definitions: let}
\label{\detokenize{proof-engine/ltac:local-definitions-let}}\index{let (tactic)@\spxentry{let}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.let}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{let~\DUrole{repeat-wrapper}{\DUrole{repeat}{rec}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-let_clause}]{\sphinxcrossref{\DUrole{hole}{let\_clause}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-let_clause}]{\sphinxcrossref{\DUrole{hole}{let\_clause}}}}}\DUrole{notation-sup}{*}}~in~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-let_clause}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-let_clause}]{\sphinxcrossref{\DUrole{hole}{let\_clause}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} := {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} := {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Binds symbols within {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}.  {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let}}}}} evaluates each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-let_clause}]{\sphinxcrossref{\DUrole{hole}{let\_clause}}}}}}}, substitutes
the bound variables into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} and then evaluates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}.  There are
no dependencies between the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-let_clause}]{\sphinxcrossref{\DUrole{hole}{let\_clause}}}}}}}s.

\sphinxAtStartPar
Use {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let}}}}} \sphinxcode{\sphinxupquote{rec}} to create recursive or mutually recursive bindings, which
causes the definitions to be evaluated lazily.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Function construction and application}
\label{\detokenize{proof-engine/ltac:function-construction-and-application}}
\sphinxAtStartPar
A parameterized tactic can be built anonymously (without resorting to
local definitions) with:
\index{fun (tactic)@\spxentry{fun}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.fun}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fun~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}}~=>~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}
\sphinxAtStartPar
Indeed, local definitions of functions are syntactic sugar for binding
a \sphinxcode{\sphinxupquote{\DUrole{notation}{fun}}} tactic to an identifier.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fun}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fun}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-binder_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Functions can return values of any type.

\sphinxAtStartPar
A function application is an expression of the form:


\begin{savenotes}\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_arg}]{\sphinxcrossref{\DUrole{hole}{tactic\_arg}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} must be bound to a \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ function
with at least as many arguments as the provided \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_arg}]{\sphinxcrossref{\DUrole{hole}{tactic\_arg}}}}}}}s.
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tactic_arg}]{\sphinxcrossref{\DUrole{hole}{tactic\_arg}}}}}}}s are evaluated before the function is applied
or partially applied.

\sphinxAtStartPar
Functions may be defined with the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fun}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fun}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let}}}}} tactics
and with the {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Ltac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac}}}}} command.

\end{fulllineitems}\end{savenotes}



\paragraph{Pattern matching on terms: match}
\label{\detokenize{proof-engine/ltac:pattern-matching-on-terms-match}}\index{lazymatch (tactic)@\spxentry{lazymatch}\spxextra{tactic}}\index{match (tactic)@\spxentry{match}\spxextra{tactic}}\index{multimatch (tactic)@\spxentry{multimatch}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.lazymatch}}\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.match}}\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.multimatch}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_key}]{\sphinxcrossref{\DUrole{hole}{match\_key}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{term}}$}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}}~=>~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}~end}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-match_key}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_key}]{\sphinxcrossref{\DUrole{hole}{match\_key}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{lazymatch}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{match}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{multimatch}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-match_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{context \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-cpattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.lazymatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazymatch}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch}}}}} are {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr1}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr1}}}}}s.

\sphinxAtStartPar
Evaluates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{term}}$}}}}}}}, which must yield a term, and matches it
sequentially with the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_pattern}}}}}s, which may have
metavariables.  When a match is found, metavariable values are substituted
into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}, which is then applied.

\sphinxAtStartPar
Matching may continue depending on whether  \sphinxcode{\sphinxupquote{lazymatch}}, \sphinxcode{\sphinxupquote{match}} or \sphinxcode{\sphinxupquote{multimatch}}
is specified.

\sphinxAtStartPar
In the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_pattern}}}}}s, metavariables have the form \sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, whereas
in the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}s, the question mark is omitted.  Choose your metavariable
names with care to avoid name conflicts.  For example, if you use the metavariable \sphinxcode{\sphinxupquote{S}},
then the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} can't use \sphinxcode{\sphinxupquote{S}} to refer to the constructor of \sphinxcode{\sphinxupquote{nat}}
without qualifying the constructor as \sphinxcode{\sphinxupquote{Datatypes.S}}.

\sphinxAtStartPar
Matching is non\sphinxhyphen{}linear: if a
metavariable occurs more than once, each occurrence must match the same
expression.  Expressions match if they are syntactically equal or are
{\hyperref[\detokenize{language/core/conversion:term-alpha-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{α\sphinxhyphen{}convertible}}}}.
Matching is first\sphinxhyphen{}order except on variables of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{@?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
that occur in the head position of an application. For these variables,
matching is second\sphinxhyphen{}order and returns a functional term.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{lazymatch}}}] \leavevmode
\sphinxAtStartPar
Causes the match to commit to the first matching branch
rather than trying a new match if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} fails.
{\hyperref[\detokenize{proof-engine/ltac:match-vs-lazymatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\item[{\sphinxcode{\sphinxupquote{match}}}] \leavevmode
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} fails, continue matching with the next branch.
Failures in subsequent tactics (after the \sphinxcode{\sphinxupquote{match}}) will not cause selection
of a new branch.  Examples {\hyperref[\detokenize{proof-engine/ltac:match-vs-lazymatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}} and
{\hyperref[\detokenize{proof-engine/ltac:match-vs-multimatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\item[{\sphinxcode{\sphinxupquote{multimatch}}}] \leavevmode
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} fails, continue matching with the next branch.
When an \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} succeeds for a branch, subsequent failures
(after the \sphinxcode{\sphinxupquote{multimatch}}) causing consumption of all the successes
of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} trigger selection of a new matching branch.
{\hyperref[\detokenize{proof-engine/ltac:match-vs-multimatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{…}}} is, in fact, shorthand for {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}} {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch}}}}} \sphinxcode{\sphinxupquote{…}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}}}}}}] \leavevmode
\sphinxAtStartPar
The syntax of {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cpattern}}}}} is
the same as that of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}s, but it can contain pattern matching
metavariables in the form \sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.  \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}} can be used to match
irrelevant terms.  {\hyperref[\detokenize{proof-engine/ltac:match-with-holes-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\sphinxAtStartPar
When a metavariable in 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.

\sphinxAtStartPar
There is also a special notation for second\sphinxhyphen{}order pattern matching: in an
applicative pattern of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{@?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} … {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{n}}$}}}}}}},
the variable {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} matches any complex expression with (possible)
dependencies in the variables \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}} and returns a functional term
of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{fun {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} … {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{n}}$}}}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{description}
\phantomsection\label{\detokenize{proof-engine/ltac:match-term-context}}\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{context \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
Matches any term with a subterm matching {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cpattern}}}}}. If there is a match
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is present, it is assigned the "matched
context", i.e. the initial term where the matched subterm is replaced by a
hole.  Note that \sphinxcode{\sphinxupquote{context}}
(with very similar syntax) appearing after the \sphinxcode{\sphinxupquote{=>}} is the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context}}}}} tactic.

\sphinxAtStartPar
For {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch}}}}}, if the evaluation of the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}
fails, the next matching subterm is tried. If no further subterm matches, the next branch
is tried.  Matching subterms are considered from top to bottom and from left to
right (with respect to the raw printing obtained by setting the
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} flag).  {\hyperref[\detokenize{proof-engine/ltac:match-term-context-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\end{description}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}] \leavevmode
\sphinxAtStartPar
The tactic to apply if the construct matches.  Metavariable values from the pattern
match are substituted
into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} before it's applied.  Note that metavariables are not
prefixed with the question mark as they are in {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cpattern}}}}}.

\sphinxAtStartPar
If {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} evaluates to a tactic, then it is
applied. If the tactic succeeds, the result of the match expression is
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}}.  If {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} does not evaluate
to a tactic, that value is the result of the match expression.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} is a tactic with backtracking points, then subsequent
failures after a {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.lazymatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazymatch}}}}} or {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch}}}}} (but not {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}}) can cause
backtracking into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} to select its next success.
({\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{…}}} is equivalent to {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}} {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch}}}}} \sphinxcode{\sphinxupquote{…}}.
The {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.once}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{once}}}}} prevents backtracking into the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} after it has succeeded.)

\end{description}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Each \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ construct is processed in two phases: an evaluation phase and an execution phase.
In most cases, tactics that may change the proof state are applied in the second phase.
(Tactics that generate integer, string or syntactic values, such as {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fresh}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fresh}}}}},
are processed during the evaluation phase.)

\sphinxAtStartPar
Unlike other tactics, \sphinxcode{\sphinxupquote{*match*}} tactics get their first success (applying tactics to do
so) as part of the evaluation phase.  Among other things, this can affect how early
failures are processed in {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_fails}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_fails}}}}}.  Please see the note in {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_fails}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_fails}}}}}.
\end{sphinxadmonition}
\index{Expression does not evaluate to a tactic (error)@\spxentry{Expression does not evaluate to a tactic}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.Expression-does-not-evaluate-to-a-tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Expression~does~not~evaluate~to~a~tactic.}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} must evaluate to a tactic.

\end{fulllineitems}\end{savenotes}

\index{No matching clauses for match (error)@\spxentry{No matching clauses for match}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
For at least one of the focused goals, there is no branch that matches
its pattern \sphinxstyleemphasis{and} gets at least one success for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}.

\end{fulllineitems}\end{savenotes}

\index{Argument of match does not evaluate to a term (error)@\spxentry{Argument of match does not evaluate to a term}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
This happens when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr$_{\text{term}}$}}}}}}} does not denote a term.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\phantomsection\label{\detokenize{proof-engine/ltac:match-vs-lazymatch-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Comparison of lazymatch and match}

\sphinxAtStartPar
In {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.lazymatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazymatch}}}}}, if {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} fails, the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.lazymatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazymatch}}}}} fails;
it doesn't look for further matches.  In {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}}, if {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} fails
in a matching branch, it will try to match on subsequent branches.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{n}{lazymatch} \PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \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}{Tactic} \PYG{n}{failure}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{match} \PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \PYG{n}{branch} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/ltac:match-vs-multimatch-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Comparison of match and multimatch}

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} tactics are only evaluated once, whereas {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch}}}}}
tactics may be evaluated more than once if the following constructs trigger backtracking:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k}{match} \PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end} \PYG{o}{;}
\PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \PYG{n}{branch} \PYG{n}{A}
    \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}{Tactic} \PYG{n}{failure}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{n}{multimatch} \PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end} \PYG{o}{;}
\PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \PYG{n}{branch} \PYG{n}{A}
    \PYG{n}{branch} \PYG{l+m+mi}{2}
    \PYG{n}{branch} \PYG{n}{A}
    \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}{Tactic} \PYG{n}{failure}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/ltac:match-with-holes-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Matching a pattern with holes}

\sphinxAtStartPar
Notice the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}} prints \sphinxcode{\sphinxupquote{(z + 1)}} while the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.pose}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose}}}}} substitutes
\sphinxcode{\sphinxupquote{(x + 1)}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{match} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{3}\PYG{o}{)} \PYG{k}{with}
\PYG{o}{|} \PYG{k}{fun} \PYG{n}{z} \PYG{o}{=\PYGZgt{}} \PYG{o}{?}\PYG{n}{y} \PYG{o}{*} \PYG{l+m+mi}{3} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{y =}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{y}\PYG{o}{;} \PYG{k}{pose} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{z}\PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{y} \PYG{o}{*} \PYG{l+m+mi}{5}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{y} \PYG{o}{=} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{n} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{5} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/ltac:match-term-context-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Multiple matches for a "context" pattern.}

\sphinxAtStartPar
Internally "x <> y" is represented as "(\textasciitilde{} (x = y))", which produces the
first match.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{f} \PYG{n}{t} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{t} \PYG{k}{with}
           \PYG{o}{|} \PYG{n}{context} \PYG{o}{[} \PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{o}{?}\PYG{n}{t}\PYG{o}{)} \PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{?t = }\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{t}\PYG{o}{;} \PYG{n}{fail}
           \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac}
           \PYG{k}{end}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{f} \PYG{o}{(}\PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{n}{False}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{?}\PYG{n}{t} \PYG{o}{=}  \PYG{o}{(}\PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{n}{False}\PYG{o}{)}\PYG{o}{)}
    \PYG{o}{?}\PYG{n}{t} \PYG{o}{=}  \PYG{n}{True}
    \PYG{o}{?}\PYG{n}{t} \PYG{o}{=}  \PYG{n}{False}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}


\paragraph{Pattern matching on goals and hypotheses: match goal}
\label{\detokenize{proof-engine/ltac:pattern-matching-on-goals-and-hypotheses-match-goal}}\label{\detokenize{proof-engine/ltac:ltac-match-goal}}\index{lazymatch goal (tactic)@\spxentry{lazymatch goal}\spxextra{tactic}}\index{match goal (tactic)@\spxentry{match goal}\spxextra{tactic}}\index{multimatch goal (tactic)@\spxentry{multimatch goal}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.lazymatch-goal}}\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.match-goal}}\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.multimatch-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_key}]{\sphinxcrossref{\DUrole{hole}{match\_key}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{reverse}\DUrole{notation-sup}{?}}~goal~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_pattern}]{\sphinxcrossref{\DUrole{hole}{goal\_pattern}}}}~=>~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}~end}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-goal_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_pattern}]{\sphinxcrossref{\DUrole{hole}{goal\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_hyp}]{\sphinxcrossref{\DUrole{hole}{match\_hyp}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} |\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_hyp}]{\sphinxcrossref{\DUrole{hole}{match\_hyp}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} |\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-match_hyp}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_hyp}]{\sphinxcrossref{\DUrole{hole}{match\_hyp}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} : {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} := {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} := {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}} {]} : {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.lazymatch-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazymatch goal}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch goal}}}}} are {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l1_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l1\_tactic}}}}}s.

\sphinxAtStartPar
Use this form to match hypotheses and/or goals in the local context.  These patterns have zero or
more subpatterns to match hypotheses followed by a subpattern to match the conclusion.  Except for the
differences noted below, this works the same as the corresponding \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_key}]{\sphinxcrossref{\DUrole{hole}{match\_key}}}} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}} construct
(see {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}}).  Each current goal is processed independently.

\sphinxAtStartPar
Matching is non\sphinxhyphen{}linear: if a
metavariable occurs more than once, each occurrence must match the same
expression.  Within a single term, expressions match if they are syntactically equal or
{\hyperref[\detokenize{language/core/conversion:term-alpha-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{α\sphinxhyphen{}convertible}}}}.  When a metavariable is used across
multiple hypotheses or across a hypothesis and the current goal, the expressions match if
they are {\hyperref[\detokenize{language/core/conversion:term-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{convertible}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_hyp}]{\sphinxcrossref{\DUrole{hole}{match\_hyp}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}}}}}}] \leavevmode
\sphinxAtStartPar
Patterns to match with hypotheses.  Each pattern must match a distinct hypothesis in order
for the branch to match.

\sphinxAtStartPar
Hypotheses have the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{:= {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{binder}}$}}}}}\DUrole{notation-sup}{?}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}.  Patterns bind each of
these nonterminals separately:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabular}[t]{|\X{2}{3}|\X{1}{3}|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
Pattern syntax
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Example pattern
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} : {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern$_{\text{type}}$}}}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{n : ?t}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} := {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern$_{\text{binder}}$}}}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{n := ?b}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{binder}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{n := ?b : ?t}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} := {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern$_{\text{binder}}$}}}} {]} : {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern$_{\text{type}}$}}}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{n := {[} ?b {]} : ?t}}
\\
\hline
\end{tabular}
\par
\sphinxattableend\end{savenotes}
\begin{quote}

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} can't have a \sphinxcode{\sphinxupquote{?}}.  Note that the last two forms are equivalent except that:
\begin{itemize}
\item {} 
\sphinxAtStartPar
if the \sphinxcode{\sphinxupquote{:}} in the third form has been bound to something else in a notation, you must use the fourth form.
Note that cmd:\sphinxcode{\sphinxupquote{Require Import}} \sphinxcode{\sphinxupquote{ssreflect}} loads a notation that does this.

\item {} 
\sphinxAtStartPar
a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{binder}}$}}}}}}} such as \sphinxcode{\sphinxupquote{{[} ?l {]}}} (e.g., denoting a singleton list after
{\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} \sphinxcode{\sphinxupquote{ListNotations}}) must be parenthesized or, for the fourth form,
use double brackets: \sphinxcode{\sphinxupquote{{[} {[} ?l {]} {]}}}.

\end{itemize}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{binder}}$}}}}}}}s in the form \sphinxcode{\sphinxupquote{{[}?x ; ?y{]}}} for a list are not parsed correctly.  The workaround is
to add parentheses or to use the underlying term instead of the notation, i.e. \sphinxcode{\sphinxupquote{(cons ?x ?y)}}.
\end{quote}

\sphinxAtStartPar
If there are multiple {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_hyp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_hyp}}}}}s in a branch, there may be multiple ways to match them to hypotheses.
For {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.multimatch-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multimatch goal}}}}}, if the evaluation of the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} fails,
matching will continue with the next hypothesis combination.  When those are exhausted,
the next alternative from any \sphinxcode{\sphinxupquote{context}} constructs in the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_pattern}}}}}s is tried and then,
when the context alternatives are exhausted, the next branch is tried.
{\hyperref[\detokenize{proof-engine/ltac:match-goal-multiple-hyps-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\item[{\sphinxcode{\sphinxupquote{reverse}}}] \leavevmode
\sphinxAtStartPar
Hypothesis matching for {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_hyp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_hyp}}}}}s normally begins by matching them from left to right,
to hypotheses, last to first.  Specifying \sphinxcode{\sphinxupquote{reverse}} begins matching in the reverse order, from
first to last.  {\hyperref[\detokenize{proof-engine/ltac:match-goal-hyps-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Normal}}}} and {\hyperref[\detokenize{proof-engine/ltac:match-goal-hyps-rev-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{reverse}}}} examples.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{|\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match_pattern}]{\sphinxcrossref{\DUrole{hole}{match\_pattern}}}}}}}}] \leavevmode
\sphinxAtStartPar
A pattern to match with the current goal

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-goal_pattern}]{\sphinxcrossref{\DUrole{hole}{goal\_pattern}}}} with {[} ... {]}}}}}] \leavevmode
\sphinxAtStartPar
The square brackets don't affect the semantics.  They are permitted for aesthetics.

\end{description}
\index{No matching clauses for match goal (error)@\spxentry{No matching clauses for match goal}\spxextra{error}}

\begin{savenotes}\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.}}}}
\sphinxAtStartPar
No clause succeeds, i.e. all matching patterns, if any, fail at the
application of the {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Examples:

\phantomsection\label{\detokenize{proof-engine/ltac:match-goal-hyps-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Matching hypotheses}

\sphinxAtStartPar
Hypotheses are matched from the last hypothesis (which is by default the newest
hypothesis) to the first until the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} succeeds.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}

\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{B}
      \PYG{n}{H1} \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}{B}

\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{apply }\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{H}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{H}
\PYG{k}{end}\PYG{o}{.}
    \PYG{k}{apply}  \PYG{n}{H1}
    \PYG{k}{apply}  \PYG{n}{H0}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/ltac:match-goal-hyps-rev-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Matching hypotheses with reverse}

\sphinxAtStartPar
Hypotheses are matched from the first hypothesis to the last until the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} succeeds.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}

\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{B}
      \PYG{n}{H1} \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}{B}

\PYG{k}{match} \PYG{n}{reverse} \PYG{n}{goal} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{apply }\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{H}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{H}
\PYG{k}{end}\PYG{o}{.}
    \PYG{k}{apply}  \PYG{n}{A}
    \PYG{k}{apply}  \PYG{n}{B}
    \PYG{k}{apply}  \PYG{n}{H}
    \PYG{k}{apply}  \PYG{n}{H0}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}
\phantomsection\label{\detokenize{proof-engine/ltac:match-goal-multiple-hyps-ex}}\begin{quote}

\begin{sphinxadmonition}{note}{Example: Multiple ways to match hypotheses}

\sphinxAtStartPar
Every possible match for the hypotheses is evaluated until the right\sphinxhyphen{}hand
side succeeds.  Note that \sphinxcode{\sphinxupquote{H1}} and \sphinxcode{\sphinxupquote{H2}} are never matched to the same hypothesis.
Observe that the number of permutations can grow as the factorial
of the number of hypotheses and hypothesis patterns.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}

\PYG{k}{intros} \PYG{n}{A} \PYG{n}{B} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \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}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}

\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{H1} \PYG{o}{:} \PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{n}{H2} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{match }\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{H1} \PYG{n}{H2}\PYG{o}{;} \PYG{n}{fail}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{idtac}
\PYG{k}{end}\PYG{o}{.}
    \PYG{k}{match}  \PYG{n}{B} \PYG{n}{H}
    \PYG{k}{match}  \PYG{n}{A} \PYG{n}{H}
    \PYG{k}{match}  \PYG{n}{H} \PYG{n}{B}
    \PYG{k}{match}  \PYG{n}{A} \PYG{n}{B}
    \PYG{k}{match}  \PYG{n}{H} \PYG{n}{A}
    \PYG{k}{match}  \PYG{n}{B} \PYG{n}{A}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}


\paragraph{Filling a term context}
\label{\detokenize{proof-engine/ltac:filling-a-term-context}}
\sphinxAtStartPar
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:
\index{context (tactic)@\spxentry{context}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.context}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{context~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{[}~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{]}}}}}
\sphinxAtStartPar
Returns the term matched with the \sphinxcode{\sphinxupquote{context}} pattern (described {\hyperref[\detokenize{proof-engine/ltac2:match-term-context}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}})
substituting {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} for the hole created by the pattern.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.context}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-value_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{value\_tactic}}}}}.
\index{Not a context variable (error)@\spxentry{Not a context variable}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}

\index{Unbound context identifier ‘ident’ (error)@\spxentry{Unbound context identifier ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.Unbound-context-identifier-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unbound~context~identifier~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example: Substituting a matched context}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k}{match} \PYG{n}{goal} \PYG{k}{with}
\PYG{o}{|} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{n}{context} \PYG{n}{G} \PYG{o}{[}\PYG{n}{True}\PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{k}{let} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{context} \PYG{n}{G} \PYG{o}{[}\PYG{n}{False}\PYG{o}{]} \PYG{k}{in} \PYG{k+kr}{idtac} \PYG{n}{x}
\PYG{k}{end}\PYG{o}{.}
    \PYG{o}{(}\PYG{n}{False} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{Generating fresh hypothesis names}
\label{\detokenize{proof-engine/ltac:generating-fresh-hypothesis-names}}
\sphinxAtStartPar
Tactics sometimes need to generate new names for hypothesis.  Letting Coq
choose a name with the intro tactic is not so good since it is
very awkward to retrieve that name. The following
expression returns an identifier:
\index{fresh (tactic)@\spxentry{fresh}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.fresh}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fresh~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}\DUrole{notation-sup}{*}}}}}}~
\sphinxAtStartPar
Returns a fresh identifier name (i.e. one that is not already used in the local context
and not previously returned by {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fresh}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fresh}}}}} in the current {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}).
The fresh identifier is formed by concatenating the final {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} of each {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}
(dropping any qualified components) and each specified {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}.
If the resulting name is already used, a number is appended to make it fresh.
If no arguments are given, the name is a fresh derivative of the name \sphinxcode{\sphinxupquote{H}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
We recommend generating the fresh identifier immediately before
adding it to the local context.  Using {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fresh}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fresh}}}}} in a local function
may not work as you expect:

\sphinxAtStartPar
Successive calls to {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fresh}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fresh}}}}} give distinct names even if the names haven't
yet been added to the local context:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{x} \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}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{let} \PYG{n}{a} \PYG{o}{:=} \PYG{n}{fresh} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{in}
\PYG{k}{let} \PYG{n}{b} \PYG{o}{:=} \PYG{n}{fresh} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{in}
\PYG{k+kr}{idtac} \PYG{n}{a} \PYG{n}{b}\PYG{o}{.}
    \PYG{n}{x0} \PYG{n}{x1}
\end{sphinxVerbatim}

\sphinxAtStartPar
When applying {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fresh}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fresh}}}}} in a function, the name is chosen based on the
tactic context at the point where the function was defined:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{let} \PYG{n}{a} \PYG{o}{:=} \PYG{n}{fresh} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{in}
\PYG{k}{let} \PYG{n}{f} \PYG{o}{:=} \PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{fresh} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{in}
\PYG{k}{let} \PYG{n}{c} \PYG{o}{:=} \PYG{n}{f} \PYG{n+nb+bp}{()} \PYG{k}{in}
\PYG{k}{let} \PYG{n}{d} \PYG{o}{:=} \PYG{n}{f} \PYG{n+nb+bp}{()} \PYG{k}{in}
\PYG{k+kr}{idtac} \PYG{n}{a} \PYG{n}{c} \PYG{n}{d}\PYG{o}{.}
    \PYG{n}{x0} \PYG{n}{x1} \PYG{n}{x1}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fresh}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fresh}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-value_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{value\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Computing in a term: eval}
\label{\detokenize{proof-engine/ltac:computing-in-a-term-eval}}
\sphinxAtStartPar
Evaluation of a term can be performed with:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{eval {\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}

\sphinxAtStartPar
See {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eval}}}}}.  {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eval}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-value_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{value\_tactic}}}}}.


\paragraph{Getting the type of a term}
\label{\detokenize{proof-engine/ltac:getting-the-type-of-a-term}}\index{type of (tactic)@\spxentry{type of}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.type-of}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{type~of~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\sphinxAtStartPar
This tactic returns the type of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.type-of}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type of}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-value_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{value\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Manipulating untyped terms: type\_term}
\label{\detokenize{proof-engine/ltac:manipulating-untyped-terms-type-term}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\DUrole{notation}{uconstr : ( {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}} construct can be used to build an untyped term.
See {\hyperref[\detokenize{proof-engine/ltac:grammar-token-syn_value}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{syn\_value}}}}}.
\index{type\_term (tactic)@\spxentry{type\_term}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.type_term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{type\_term~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}
\sphinxAtStartPar
In \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$, an untyped term can contain references to hypotheses or to
\sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ variables containing typed or untyped terms. An untyped term can be
type checked with {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.type_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type\_term}}}}} whose argument is parsed as an
untyped term and returns a well\sphinxhyphen{}typed term which can be used in tactics.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.type_term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type\_term}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-value_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{value\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\paragraph{Counting goals: numgoals}
\label{\detokenize{proof-engine/ltac:counting-goals-numgoals}}\index{numgoals (tactic)@\spxentry{numgoals}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.numgoals}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{numgoals}}}}
\sphinxAtStartPar
The number of goals under focus can be recovered using the \sphinxcode{\sphinxupquote{\DUrole{notation}{numgoals}}}
function. Combined with the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.guard}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{guard}}}}} tactic below, it can be used to
branch over the number of goals produced by previous tactics.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.numgoals}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{numgoals}}}}} is a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-value_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{value\_tactic}}}}}.

\begin{sphinxadmonition}{note}{Example}

\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}{[|}\PYG{k}{split}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\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}\end{savenotes}



\paragraph{Testing boolean expressions: guard}
\label{\detokenize{proof-engine/ltac:testing-boolean-expressions-guard}}\index{guard (tactic)@\spxentry{guard}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.guard}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{guard~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-int_or_var}]{\sphinxcrossref{\DUrole{hole}{int\_or\_var}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-comparison}]{\sphinxcrossref{\DUrole{hole}{comparison}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-int_or_var}]{\sphinxcrossref{\DUrole{hole}{int\_or\_var}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-int_or_var}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-int_or_var}]{\sphinxcrossref{\DUrole{hole}{int\_or\_var}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-comparison}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-comparison}]{\sphinxcrossref{\DUrole{hole}{comparison}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{=}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{<}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{<=}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{>}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{>=}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Tests a boolean expression.  If the expression evaluates to true,
it succeeds without affecting the proof.  The tactic fails if the
expression is false.

\sphinxAtStartPar
The accepted tests are simple integer comparisons.

\begin{sphinxadmonition}{note}{Example}

\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}{[|}\PYG{k}{split}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\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{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 (error)@\spxentry{Condition not satisfied}\spxextra{error}}

\begin{savenotes}\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{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Proving a subgoal as a separate lemma: abstract}
\label{\detokenize{proof-engine/ltac:proving-a-subgoal-as-a-separate-lemma-abstract}}\index{abstract (tactic)@\spxentry{abstract}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.abstract}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{abstract~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{name}}$}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Does a {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.solve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{solve}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr2}}}} {]}}}} and saves the subproof as an auxiliary lemma.
if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{name}}$}}}}}}} is specified, the lemma is saved with that name; otherwise
the lemma is saved with the name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_subproof}}\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}} where
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the name of the current goal (e.g. the theorem name) and {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}
is chosen to get a fresh name.  If the proof is closed with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}, the auxiliary lemma
is inlined in the final proof term.

\sphinxAtStartPar
This is useful with tactics such as
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}} that generate huge proof terms with many intermediate
goals.  It can significantly reduce peak memory use.  In most cases it doesn't
have a significant impact on run time.  One case in which it can reduce run time
is when a tactic \sphinxcode{\sphinxupquote{foo}} is known to always pass type checking when it
succeeds, such as in reflective proofs.  In this case, the idiom
"{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}} {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact\_no\_check}}}}} \sphinxcode{\sphinxupquote{foo}}" will save half the type
checking type time compared to "{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact}}}}} \sphinxcode{\sphinxupquote{foo}}".

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The abstract tactic, while very useful, still has some known
limitations.  See \sphinxhref{https://github.com/coq/coq/issues/9146}{\#9146}%
\begin{footnote}[53]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9146}
%
\end{footnote} for more
details. We recommend caution when using it in some
"non\sphinxhyphen{}standard" contexts. In particular, \sphinxcode{\sphinxupquote{abstract}} doesn't
work properly when used inside quotations \sphinxcode{\sphinxupquote{ltac:(...)}}.
If used as part of typeclass resolution, it may produce incorrect
terms when in polymorphic universe mode.
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
Provide \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{name}}$}}}}}}} at your own risk; explicitly named and reused subterms
don’t play well with asynchronous proofs.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}

\index{transparent\_abstract (tactic)@\spxentry{transparent\_abstract}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.transparent_abstract}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{transparent\_abstract~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Like {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}}, but save the subproof in a transparent lemma with a name in
the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\DUrole{notation}{\_subterm}}}\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}}}}.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
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}
\index{Proof is not complete. (abstract) (error)@\spxentry{Proof is not complete. (abstract)}\spxextra{error}}

\begin{savenotes}\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{savenotes}


\end{fulllineitems}\end{savenotes}



\subsubsection{Tactic toplevel definitions}
\label{\detokenize{proof-engine/ltac:tactic-toplevel-definitions}}

\paragraph{Defining \sphinxstyleliteralintitle{\sphinxupquote{L}}$_{\text{tac}}$ symbols}
\label{\detokenize{proof-engine/ltac:defining-ltac-symbols}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ toplevel definitions are made as follows:

\index{::=@\spxentry{::=}}\ignorespaces \index{Ltac (command)@\spxentry{Ltac}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:cmd.Ltac}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacdef_body}]{\sphinxcrossref{\DUrole{hole}{tacdef\_body}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacdef_body}]{\sphinxcrossref{\DUrole{hole}{tacdef\_body}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-tacdef_body}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacdef_body}]{\sphinxcrossref{\DUrole{hole}{tacdef\_body}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{*}} \DUrole{alternative}{\DUrole{alternative-block}{:=}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{::=}} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Defines or redefines an \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ symbol.

\sphinxAtStartPar
If the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute is specified, the definition will not be
exported outside the current module.
\begin{description}
\item[{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}}] \leavevmode
\sphinxAtStartPar
Name of the symbol being defined or redefined.  For definitions, {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}
must be a simple {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{*}}}}}}] \leavevmode
\sphinxAtStartPar
If specified, the symbol defines a function with the given parameter names.
If no names are specified, {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is assigned the value of {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}}.

\item[{\sphinxcode{\sphinxupquote{:=}}}] \leavevmode
\sphinxAtStartPar
Defines a user\sphinxhyphen{}defined symbol, but gives an error if the symbol has already
been defined.
\index{There is already an Ltac named ‘qualid’ (error)@\spxentry{There is already an Ltac named ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.There-is-already-an-Ltac-named-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{There~is~already~an~Ltac~named~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{::=}}}] \leavevmode
\sphinxAtStartPar
Redefines an existing user\sphinxhyphen{}defined symbol, but gives an error if the
symbol doesn't exist.  Note that {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Tactic-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Tactic Notation}}}}}s
do not count as user\sphinxhyphen{}defined tactics for \sphinxcode{\sphinxupquote{::=}}.  If {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} is not
specified, the redefinition applies across module boundaries.
\index{There is no Ltac named ‘qualid’ (error)@\spxentry{There is no Ltac named ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.There-is-no-Ltac-named-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{There~is~no~Ltac~named~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\end{fulllineitems}\end{savenotes}


\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacdef_body}]{\sphinxcrossref{\DUrole{hole}{tacdef\_body}}}}}\DUrole{notation-sup}{*}}}}}}] \leavevmode
\sphinxAtStartPar
Permits definition of mutually recursive tactics.

\end{description}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The following definitions are equivalent:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} := {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} := fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{+}} => {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}

\end{itemize}
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{Printing \sphinxstyleliteralintitle{\sphinxupquote{L}}$_{\text{tac}}$ tactics}
\label{\detokenize{proof-engine/ltac:printing-ltac-tactics}}\index{Print Ltac (command)@\spxentry{Print Ltac}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Defined \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ functions can be displayed using this command.

\end{fulllineitems}\end{savenotes}

\index{Print Ltac Signatures (command)@\spxentry{Print Ltac Signatures}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This command displays a list of all user\sphinxhyphen{}defined tactics, with their arguments.

\end{fulllineitems}\end{savenotes}



\subsubsection{Examples of using \sphinxstyleliteralintitle{\sphinxupquote{L}}$_{\text{tac}}$}
\label{\detokenize{proof-engine/ltac:examples-of-using-ltac}}\label{\detokenize{proof-engine/ltac:ltac-examples}}

\paragraph{Proof that the natural numbers have at least two elements}
\label{\detokenize{proof-engine/ltac:proof-that-the-natural-numbers-have-at-least-two-elements}}
\begin{sphinxadmonition}{note}{Example: Proof that the natural numbers have at least two elements}

\sphinxAtStartPar
The first example shows how to use pattern matching over the proof
context to prove that natural numbers have at least two
elements. This can be done as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{card\PYGZus{}nat} \PYG{o}{:}
  \PYG{o}{\PYGZti{}} \PYG{k}{exists} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{k}{forall} \PYG{n}{z}\PYG{o}{:}\PYG{n}{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{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\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{k}{exists} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{k}{forall} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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}{.}
\PYG{k}{intros} \PYG{o}{(}\PYG{n}{x} \PYG{o}{\PYGZam{}} \PYG{n}{y} \PYG{o}{\PYGZam{}} \PYG{n}{Hz}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{Hz} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{z} \PYG{o}{:} \PYG{n}{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{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{k}{destruct} \PYG{o}{(}\PYG{n}{Hz} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{Hz} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{Hz} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{8} \PYG{n}{goals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{Hz} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z} \PYG{o}{\PYGZbs{}/} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{1}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \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}{False}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{6} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{7} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{8} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
\end{sphinxVerbatim}

\sphinxAtStartPar
At this point, the {\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}} tactic would finish the job:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{all}\PYG{o}{:} \PYG{k+kp}{congruence}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
But for the purpose of the example, let's craft our own custom
tactic to solve this:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{all}\PYG{o}{:} \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
     \PYG{o}{|} \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}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{assert} \PYG{o}{(}\PYG{n}{b} \PYG{o}{=} \PYG{n}{c}\PYG{o}{)} \PYG{k+kp}{by} \PYG{n}{now} \PYG{k}{transitivity} \PYG{n}{a}
     \PYG{k}{end}\PYG{o}{.}
    \PYG{l+m+mi}{8} \PYG{n}{goals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{Hz} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{z} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z} \PYG{o}{\PYGZbs{}/} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{1}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{2}
      \PYG{n}{H2} \PYG{o}{:} \PYG{l+m+mi}{1} \PYG{o}{=} \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}{False}
    
    \PYG{n}{goal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{6} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{7} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}
    \PYG{n}{goal} \PYG{l+m+mi}{8} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}

\PYG{n}{all}\PYG{o}{:} \PYG{k+kp}{discriminate}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Notice that all the (very similar) cases coming from the three
eliminations (with three distinct natural numbers) are successfully
solved by a \sphinxcode{\sphinxupquote{match goal}} structure and, in particular, with only one
pattern (use of non\sphinxhyphen{}linear matching).
\end{sphinxadmonition}


\paragraph{Proving that a list is a permutation of a second list}
\label{\detokenize{proof-engine/ltac:proving-that-a-list-is-a-permutation-of-a-second-list}}
\begin{sphinxadmonition}{note}{Example: Proving that a list is a permutation of a second list}

\sphinxAtStartPar
Let's first define the permutation predicate:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Sort}\PYG{o}{.}

  \PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}

  \PYG{k+kn}{Inductive} \PYG{n}{perm} \PYG{o}{:} \PYG{n}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{o}{|} \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}{|} \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}{|} \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}{|} \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}{.}

\PYG{k+kn}{End} \PYG{n}{Sort}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Next we define an auxiliary tactic \sphinxcode{\sphinxupquote{\DUrole{name}{perm\_aux}}} which takes an
argument used to control the recursion depth. This tactic works as
follows: If the lists are identical (i.e. convertible), it
completes the proof. Otherwise, if the lists have identical heads,
it looks at their tails.  Finally, if the lists have different
heads, it rotates the first list by putting its head at the end.

\sphinxAtStartPar
Every time we perform a rotation, we decrement \sphinxcode{\sphinxupquote{\DUrole{name}{n}}}. When \sphinxcode{\sphinxupquote{\DUrole{name}{n}}}
drops down to \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{1}}}, we stop performing rotations and we fail.
The idea is to give the length of the list as the initial value of
\sphinxcode{\sphinxupquote{\DUrole{name}{n}}}. This way of counting the number of rotations will avoid
going back to a head that had been considered before.

\sphinxAtStartPar
From Section {\hyperref[\detokenize{proof-engine/ltac:ltac-syntax}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax}}}} we know that Ltac has a primitive
notion of integers, but they are only used as arguments for
primitive tactics and we cannot make computations with them. Thus,
instead, we use Coq's natural number type \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}.

\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}{|} \PYG{o}{|}\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}{|} \PYG{o}{|}\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}{|} \PYG{o}{|}\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}{|} \PYG{l+m+mi}{1} \PYG{o}{=\PYGZgt{}} \PYG{n}{fail}
     \PYG{o}{|} \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}{|} \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}

\sphinxAtStartPar
The main tactic is \sphinxcode{\sphinxupquote{\DUrole{name}{solve\_perm}}}. It computes the lengths of the
two lists and uses them as arguments to call \sphinxcode{\sphinxupquote{\DUrole{name}{perm\_aux}}} if the
lengths are equal. (If they aren't, the lists cannot be
permutations of each other.)

\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}{|} \PYG{o}{|}\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}{|} \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}

\sphinxAtStartPar
And now, here is how we can use the tactic \sphinxcode{\sphinxupquote{\DUrole{name}{solve\_perm}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{perm} \PYG{n}{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}{)}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{solve\PYGZus{}perm}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{perm} \PYG{n}{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}{)}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{solve\PYGZus{}perm}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Deciding intuitionistic propositional logic}
\label{\detokenize{proof-engine/ltac:deciding-intuitionistic-propositional-logic}}
\sphinxAtStartPar
Pattern matching on goals allows powerful backtracking when returning tactic
values. An interesting application is the problem of deciding intuitionistic
propositional logic. Considering the contraction\sphinxhyphen{}free sequent calculi LJT* of
Roy Dyckhoff {[}\hyperlink{cite.zebibliography:id19}{Dyc92}{]}, it is quite natural to code such a tactic using the
tactic language as shown below.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{basic} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
    \PYG{o}{|} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{k}{trivial}
    \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{False} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kp}{contradiction}
    \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{o}{?}\PYG{n}{A} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{k+kp}{assumption}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\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}{|} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZti{}} \PYG{o}{\PYGZus{}} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{red} \PYG{k}{in} \PYG{n}{H}
        \PYG{o}{|} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZus{}} \PYG{o}{|}\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}{|} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZbs{}/} \PYG{o}{\PYGZus{}} \PYG{o}{|}\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}{|} \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}{|}\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}{|} \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}{|} \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}{|}\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}{|} \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}{|} \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}{|} \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}{|}\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}{|} \PYG{k}{apply} \PYG{n}{H0}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
        \PYG{o}{|} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{split}
        \PYG{o}{|} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZti{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{red}
    \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{my\PYGZus{}tauto} \PYG{o}{:=}
  \PYG{n}{simplify}\PYG{o}{;} \PYG{n}{basic} \PYG{o}{|}\PYG{o}{|}
  \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
      \PYG{o}{|} \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}{|}\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}{|} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
                  \PYG{o}{|} \PYG{k}{clear} \PYG{n}{H} \PYG{o}{]}
              \PYG{o}{|} \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}{|} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZti{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{B} \PYG{o}{|}\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}{|} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
                  \PYG{o}{|} \PYG{k}{clear} \PYG{n}{H} \PYG{o}{]}
              \PYG{o}{|} \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}{|} \PYG{o}{|}\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}{|}\PYG{o}{|} \PYG{o}{(}\PYG{k}{right}\PYG{o}{;} \PYG{n}{my\PYGZus{}tauto}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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}}).

\sphinxAtStartPar
Having defined \sphinxcode{\sphinxupquote{my\_tauto}}, we can prove tautologies like these:

\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}

\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}


\paragraph{Deciding type isomorphisms}
\label{\detokenize{proof-engine/ltac:deciding-type-isomorphisms}}
\sphinxAtStartPar
A trickier problem is to decide equalities between types modulo
isomorphisms. Here, we choose to use the isomorphisms of the simply
typed λ\sphinxhyphen{}calculus with Cartesian product and unit type (see, for
example, {[}\hyperlink{cite.zebibliography:id46}{dC95}{]}). The axioms of this λ\sphinxhyphen{}calculus are given below.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{type\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Iso\PYGZus{}axioms}\PYG{o}{.}
\end{sphinxVerbatim}

\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}

\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{n}{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{n}{unit}\PYG{o}{)} \PYG{o}{=} \PYG{n}{unit}\PYG{o}{.}

\PYG{k+kn}{Axiom} \PYG{n}{AL\PYGZus{}unit} \PYG{o}{:} \PYG{o}{(}\PYG{n}{unit} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)} \PYG{o}{=} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{End} \PYG{n}{Iso\PYGZus{}axioms}\PYG{o}{.}
\end{sphinxVerbatim}

\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}{|} \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}{|} \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}{|} \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}{|} \PYG{o}{?}\PYG{n}{A} \PYG{o}{*} \PYG{n}{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}{|} \PYG{n}{unit} \PYG{o}{*} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{Com} \PYG{n}{unit} \PYG{n}{B}\PYG{o}{)}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}
    \PYG{o}{|} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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}{|} \PYG{n}{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}{|} \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}{|}\PYG{o}{|}
        \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}{|} \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}{|}\PYG{o}{|}
        \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}{|} \PYG{o}{|}\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}

\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}{|} \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}{|} \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}

\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}

\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}{|} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{=} \PYG{o}{?}\PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{k+kp}{reflexivity}
    \PYG{o}{|} \PYG{o}{|}\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}{|} \PYG{o}{|}\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}{|} \PYG{l+m+mi}{1} \PYG{o}{=\PYGZgt{}} \PYG{n}{fail}
            \PYG{o}{|} \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}

\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}{|} \PYG{o}{|}\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}{|} \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}

\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}

\sphinxAtStartPar
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 a 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
length, 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 \sphinxcode{\sphinxupquote{solve\_iso}}.

\sphinxAtStartPar
Here are examples of what can be solved by \sphinxcode{\sphinxupquote{solve\_iso}}.

\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{n}{unit} \PYG{o}{*} \PYG{n}{B} \PYG{o}{=} \PYG{n}{B} \PYG{o}{*} \PYG{o}{(}\PYG{n}{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}

\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{n}{unit} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{*} \PYG{o}{(}\PYG{n}{C} \PYG{o}{*} \PYG{n}{unit}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=}
    \PYG{o}{(}\PYG{n}{A} \PYG{o}{*} \PYG{n}{unit} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{unit}\PYG{o}{)} \PYG{o}{*} \PYG{n}{C}\PYG{o}{)} \PYG{o}{*} \PYG{o}{(}\PYG{n}{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}


\subsubsection{Debugging \sphinxstyleliteralintitle{\sphinxupquote{L}}$_{\text{tac}}$ tactics}
\label{\detokenize{proof-engine/ltac:debugging-ltac-tactics}}

\paragraph{Backtraces}
\label{\detokenize{proof-engine/ltac:backtraces}}\index{Ltac Backtrace (flag)@\spxentry{Ltac Backtrace}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:flag.Ltac-Backtrace}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~Backtrace}}}}
\sphinxAtStartPar
Setting this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} displays a backtrace on Ltac failures that can be useful
to find out what went wrong. It is disabled by default for performance
reasons.

\end{fulllineitems}\end{savenotes}



\paragraph{Tracing execution}
\label{\detokenize{proof-engine/ltac:tracing-execution}}\index{Info (command)@\spxentry{Info}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}}}
\sphinxAtStartPar
Applies {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_expr}}}}} and prints a trace of the tactics that were successfully
applied, discarding branches that failed.
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}} tactics appear in the trace as comments containing the output.

\sphinxAtStartPar
This command is valid only in proof mode.  It accepts {\hyperref[\detokenize{proof-engine/ltac:goal-selectors}]{\sphinxcrossref{\DUrole{std,std-ref}{Goal selectors}}}}.

\sphinxAtStartPar
The number \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} 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}

\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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Info} \PYG{l+m+mi}{0} \PYG{n}{t} \PYG{l+m+mi}{1}\PYG{o}{|}\PYG{o}{|}\PYG{n}{t} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{k}{exists}  \PYG{k}{with} \PYG{l+m+mi}{0}\PYG{o}{;}\PYG{o}{\PYGZlt{}}\PYG{n}{ltac\PYGZus{}plugin}\PYG{o}{::}\PYG{k+kp}{reflexivity}\PYG{o}{@}\PYG{l+m+mi}{0}\PYG{o}{\PYGZgt{}}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Undo}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Info} \PYG{l+m+mi}{1} \PYG{n}{t} \PYG{l+m+mi}{1}\PYG{o}{|}\PYG{o}{|}\PYG{n}{t} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{o}{\PYGZlt{}}\PYG{n}{ltac\PYGZus{}plugin}\PYG{o}{::}\PYG{k}{exists}\PYG{o}{@}\PYG{l+m+mi}{1}\PYG{o}{\PYGZgt{}}  \PYG{k}{with} \PYG{l+m+mi}{0}\PYG{o}{;}\PYG{n}{simple} \PYG{k}{refine} \PYG{o}{?}\PYG{n}{X11}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
The trace produced by {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Info}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Info}}}}} tries its best to be a reparsable
\sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ script, but this goal is not achievable in all generality.
So some of the output traces will contain oddities.

\sphinxAtStartPar
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 (option)@\spxentry{Info Level}\spxextra{option}}

\begin{savenotes}\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/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} is an alternative to the {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Info}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Info}}}}} command.

\sphinxAtStartPar
This will automatically print the same trace as \sphinxcode{\sphinxupquote{\DUrole{notation}{Info {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} 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{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Interactive debugger}
\label{\detokenize{proof-engine/ltac:interactive-debugger}}\index{Ltac Debug (flag)@\spxentry{Ltac Debug}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:flag.Ltac-Debug}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~Debug}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} governs the step\sphinxhyphen{}by\sphinxhyphen{}step debugger that comes with the \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ interpreter.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
When the debugger is activated, it stops at every step of the evaluation of
the current \sphinxcode{\sphinxupquote{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

\sphinxAtStartPar
newline
&
\sphinxAtStartPar
go to the next step
\\
\hline
\sphinxAtStartPar
h
&
\sphinxAtStartPar
get help
\\
\hline
\sphinxAtStartPar
r n
&
\sphinxAtStartPar
advance n steps further
\\
\hline
\sphinxAtStartPar
r string
&
\sphinxAtStartPar
advance up to the next call to “idtac string”
\\
\hline
\sphinxAtStartPar
s
&
\sphinxAtStartPar
continue current evaluation without stopping
\\
\hline
\sphinxAtStartPar
x
&
\sphinxAtStartPar
exit current evaluation
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\index{Debug mode not available in the IDE (error)@\spxentry{Debug mode not available in the IDE}\spxextra{error}}

\begin{savenotes}\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}\end{savenotes}


\sphinxAtStartPar
A non\sphinxhyphen{}interactive mode for the debugger is available via the flag:
\index{Ltac Batch Debug (flag)@\spxentry{Ltac Batch Debug}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} 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 flag is set, can then be run through
external tools such as diff.

\end{fulllineitems}\end{savenotes}



\paragraph{Profiling \sphinxstyleliteralintitle{\sphinxupquote{L}}$_{\text{tac}}$ tactics}
\label{\detokenize{proof-engine/ltac:profiling-ltac-tactics}}
\sphinxAtStartPar
It is possible to measure the time spent in invocations of primitive
tactics as well as tactics defined in \sphinxcode{\sphinxupquote{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 performance degradation can be intricate, like a slowly
performing \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ match or a sub\sphinxhyphen{}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)@\spxentry{Ltac Profiling}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:flag.Ltac-Profiling}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~Profiling}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} enables and disables the profiler.

\end{fulllineitems}\end{savenotes}

\index{Show Ltac Profile (command)@\spxentry{Show Ltac Profile}\spxextra{command}}

\begin{savenotes}\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~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{CutOff~{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Prints the profile.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{CutOff {\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}}}] \leavevmode
\sphinxAtStartPar
By default, tactics that account for less than 2\% of the total time are not displayed.
\sphinxcode{\sphinxupquote{CutOff}} lets you specify a different percentage.

\end{description}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}
\begin{quote}

\sphinxAtStartPar
Limits the profile to all tactics that start with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}. Append a period
(.) to the string if you only want exactly that name.
\end{quote}

\end{fulllineitems}\end{savenotes}

\index{Reset Ltac Profile (command)@\spxentry{Reset Ltac Profile}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Resets the profile, that is, deletes all accumulated information.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
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}\end{savenotes}


\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Lia}\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{n}{lia} \PYG{o}{|}\PYG{o}{|} \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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Ltac} \PYG{n}{Profiling}\PYG{o}{.}
\PYG{n}{tac}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}

\PYG{k+kn}{Show} \PYG{k+kn}{Ltac} \PYG{n}{Profile}\PYG{o}{.}
    \PYG{n}{total} \PYG{n}{time}\PYG{o}{:}      \PYG{l+m+mi}{8}\PYG{o}{.}\PYG{l+m+mi}{943}\PYG{n}{s}
    
     \PYG{n}{tactic}                                   \PYG{n}{local}  \PYG{n}{total}   \PYG{n}{calls}       \PYG{n}{max} 
    \PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┘}
    \PYG{n+nb+bp}{─}\PYG{n}{tac} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{\PYGZpc{}} \PYG{l+m+mi}{100}\PYG{o}{.}\PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}       \PYG{l+m+mi}{1}    \PYG{l+m+mi}{8}\PYG{o}{.}\PYG{l+m+mi}{943}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{with\PYGZus{}uniform\PYGZus{}flags}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{96}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{584}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{tauto\PYGZus{}gen}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{96}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{584}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{tauto\PYGZus{}intuitionistic}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{96}\PYG{o}{.}\PYG{l+m+mi}{4}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{584}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{n}{t\PYGZus{}tauto\PYGZus{}intuit} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{96}\PYG{o}{.}\PYG{l+m+mi}{4}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{584}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{simplif}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}  \PYG{l+m+mi}{68}\PYG{o}{.}\PYG{l+m+mi}{8}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{92}\PYG{o}{.}\PYG{l+m+mi}{7}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{571}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{is\PYGZus{}conj}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}  \PYG{l+m+mi}{17}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{17}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{28756}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{000}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{k}{elim} \PYG{n}{id} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{9}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{9}\PYG{o}{\PYGZpc{}}     \PYG{l+m+mi}{650}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{058}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{axioms}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{2}\PYG{o}{.}\PYG{l+m+mi}{7}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{6}\PYG{o}{\PYGZpc{}}       \PYG{l+m+mi}{0}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{016}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{n}{lia} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{2}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{28}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{217}\PYG{n}{s}
    \PYG{n+nb+bp}{─}\PYG{n}{xlia} \PYG{o}{(}\PYG{n}{tactic}\PYG{o}{)} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{2}\PYG{o}{.}\PYG{l+m+mi}{3}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{2}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{28}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{210}\PYG{n}{s}
    
     \PYG{n}{tactic}                                   \PYG{n}{local}  \PYG{n}{total}   \PYG{n}{calls}       \PYG{n}{max} 
    \PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┘}
    \PYG{n+nb+bp}{─}\PYG{n}{tac} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{\PYGZpc{}} \PYG{l+m+mi}{100}\PYG{o}{.}\PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}       \PYG{l+m+mi}{1}    \PYG{l+m+mi}{8}\PYG{o}{.}\PYG{l+m+mi}{943}\PYG{n}{s}
     \PYG{n+nb+bp}{├}\PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{with\PYGZus{}uniform\PYGZus{}flags}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{96}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{584}\PYG{n}{s}
     \PYG{n+nb+bp}{│}\PYG{n+nb+bp}{└}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{tauto\PYGZus{}gen}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{96}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{584}\PYG{n}{s}
     \PYG{n+nb+bp}{│}\PYG{n+nb+bp}{└}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{tauto\PYGZus{}intuitionistic}\PYG{o}{\PYGZgt{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{96}\PYG{o}{.}\PYG{l+m+mi}{4}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{584}\PYG{n}{s}
     \PYG{n+nb+bp}{│}\PYG{n+nb+bp}{└}\PYG{n}{t\PYGZus{}tauto\PYGZus{}intuit} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{96}\PYG{o}{.}\PYG{l+m+mi}{4}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{584}\PYG{n}{s}
     \PYG{n+nb+bp}{│} \PYG{n+nb+bp}{├}\PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{simplif}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}  \PYG{l+m+mi}{68}\PYG{o}{.}\PYG{l+m+mi}{8}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{92}\PYG{o}{.}\PYG{l+m+mi}{7}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{26}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{571}\PYG{n}{s}
     \PYG{n+nb+bp}{│} \PYG{n+nb+bp}{│} \PYG{n+nb+bp}{├}\PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{is\PYGZus{}conj}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}  \PYG{l+m+mi}{17}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}  \PYG{l+m+mi}{17}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{28756}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{000}\PYG{n}{s}
     \PYG{n+nb+bp}{│} \PYG{n+nb+bp}{│} \PYG{n+nb+bp}{└}\PYG{n+nb+bp}{─}\PYG{k}{elim} \PYG{n}{id} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{9}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{9}\PYG{o}{\PYGZpc{}}     \PYG{l+m+mi}{650}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{058}\PYG{n}{s}
     \PYG{n+nb+bp}{│} \PYG{n+nb+bp}{└}\PYG{n+nb+bp}{─}\PYG{o}{\PYGZlt{}}\PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Tauto}\PYG{o}{.}\PYG{n}{axioms}\PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{2}\PYG{o}{.}\PYG{l+m+mi}{7}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{6}\PYG{o}{\PYGZpc{}}       \PYG{l+m+mi}{0}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{016}\PYG{n}{s}
     \PYG{n+nb+bp}{└}\PYG{n+nb+bp}{─}\PYG{n}{lia} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{2}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{28}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{217}\PYG{n}{s}
      \PYG{n+nb+bp}{└}\PYG{n}{xlia} \PYG{o}{(}\PYG{n}{tactic}\PYG{o}{)} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{2}\PYG{o}{.}\PYG{l+m+mi}{3}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{2}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{28}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{210}\PYG{n}{s}

\PYG{k+kn}{Show} \PYG{k+kn}{Ltac} \PYG{n}{Profile} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{lia}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{total} \PYG{n}{time}\PYG{o}{:}      \PYG{l+m+mi}{8}\PYG{o}{.}\PYG{l+m+mi}{943}\PYG{n}{s}
    
     \PYG{n}{tactic}                                   \PYG{n}{local}  \PYG{n}{total}   \PYG{n}{calls}       \PYG{n}{max} 
    \PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┘}
    \PYG{n+nb+bp}{─}\PYG{n}{lia} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}   \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{1}\PYG{o}{\PYGZpc{}}   \PYG{l+m+mi}{3}\PYG{o}{.}\PYG{l+m+mi}{2}\PYG{o}{\PYGZpc{}}      \PYG{l+m+mi}{28}    \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{217}\PYG{n}{s}
    
     \PYG{n}{tactic}                                   \PYG{n}{local}  \PYG{n}{total}   \PYG{n}{calls}       \PYG{n}{max} 
    \PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┴}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{─}\PYG{n+nb+bp}{┘}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Abort}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Ltac} \PYG{n}{Profiling}\PYG{o}{.}
\end{sphinxVerbatim}
\index{start ltac profiling (tactic)@\spxentry{start ltac profiling}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.start-ltac-profiling}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{start~ltac~profiling}}}}
\sphinxAtStartPar
This tactic behaves like {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}} but enables the profiler.

\end{fulllineitems}\end{savenotes}

\index{stop ltac profiling (tactic)@\spxentry{stop ltac profiling}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.stop-ltac-profiling}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{stop~ltac~profiling}}}}
\sphinxAtStartPar
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}\end{savenotes}

\index{reset ltac profile (tactic)@\spxentry{reset ltac profile}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.reset-ltac-profile}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{reset~ltac~profile}}}}
\sphinxAtStartPar
Equivalent to the {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Reset-Ltac-Profile}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Reset Ltac Profile}}}}} command, which allows
resetting the profile from tactic scripts for benchmarking purposes.

\end{fulllineitems}\end{savenotes}

\index{show ltac profile (tactic)@\spxentry{show ltac profile}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.show-ltac-profile}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{show~ltac~profile~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{cutoff~{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Equivalent to the {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Show-Ltac-Profile}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Ltac Profile}}}}} command,
which allows displaying the profile from tactic scripts for
benchmarking purposes.

\end{fulllineitems}\end{savenotes}

\index{Ltac Profiler encountered an invalid stack (no self node). This can happen if you reset the profile during tactic execution (warning)@\spxentry{Ltac Profiler encountered an invalid stack (no self node). This can happen if you reset the profile during tactic execution}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:warn.Ltac-Profiler-encountered-an-invalid-stack-(no-self-node).-This-can-happen-if-you-reset-the-profile-during-tactic-execution}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~Profiler~encountered~an~invalid~stack~(no~self~node).~This~can~happen~if~you~reset~the~profile~during~tactic~execution}}}}
\sphinxAtStartPar
Currently, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.reset-ltac-profile}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reset ltac profile}}}}} is not very well\sphinxhyphen{}supported,
as it clears all profiling information about all tactics, including
ones above the current tactic.  As a result, the profiler has
trouble understanding where it is in tactic execution.  This mixes
especially poorly with backtracking into multi\sphinxhyphen{}success tactics.  In
general, non\sphinxhyphen{}top\sphinxhyphen{}level calls to {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.reset-ltac-profile}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reset ltac profile}}}}} should
be avoided.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
You can also pass the \sphinxcode{\sphinxupquote{\sphinxhyphen{}profile\sphinxhyphen{}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}}}}} flag 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.


\paragraph{Run\sphinxhyphen{}time optimization tactic}
\label{\detokenize{proof-engine/ltac:run-time-optimization-tactic}}\index{optimize\_heap (tactic)@\spxentry{optimize\_heap}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.optimize_heap}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{optimize\_heap}}}}
\sphinxAtStartPar
This tactic behaves like {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}}, except that running it compacts the
heap in the OCaml run\sphinxhyphen{}time system. It is analogous to the
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Optimize-Heap}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Optimize Heap}}}}} command.

\end{fulllineitems}\end{savenotes}

\index{infoH (tactic)@\spxentry{infoH}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.infoH}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{infoH~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr3}}}}}}}}
\sphinxAtStartPar
Used internally by Proof General.  See \sphinxhref{https://github.com/coq/coq/issues/12423}{\#12423}%
\begin{footnote}[54]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12423}
%
\end{footnote} for
some background.

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.infoH}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{infoH}}}}} is an {\hyperref[\detokenize{proof-engine/ltac:grammar-token-l3_tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{l3\_tactic}}}}}.

\end{fulllineitems}\end{savenotes}



\subsection{Ltac2}
\label{\detokenize{proof-engine/ltac2:ltac2}}\label{\detokenize{proof-engine/ltac2:id1}}\label{\detokenize{proof-engine/ltac2::doc}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ tactic language is probably one of the ingredients of the success of
Coq, yet it is at the same time its Achilles' heel. Indeed, \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$:
\begin{itemize}
\item {} 
\sphinxAtStartPar
has often unclear semantics

\item {} 
\sphinxAtStartPar
is very non\sphinxhyphen{}uniform due to organic growth

\item {} 
\sphinxAtStartPar
lacks expressivity (data structures, combinators, types, ...)

\item {} 
\sphinxAtStartPar
is slow

\item {} 
\sphinxAtStartPar
is error\sphinxhyphen{}prone and fragile

\item {} 
\sphinxAtStartPar
has an intricate implementation

\end{itemize}

\sphinxAtStartPar
Following the need of users who are developing huge projects relying
critically on Ltac, we believe that we should offer a proper modern language
that features at least the following:
\begin{itemize}
\item {} 
\sphinxAtStartPar
at least informal, predictable semantics

\item {} 
\sphinxAtStartPar
a type system

\item {} 
\sphinxAtStartPar
standard programming facilities (e.g., datatypes)

\end{itemize}

\sphinxAtStartPar
This new language, called Ltac2, is described in this chapter. It is still
experimental but we nonetheless encourage users to start testing it,
especially wherever an advanced tactic language is needed. The previous
implementation of Ltac, described in the previous chapter, will be referred to
as Ltac1.

\sphinxAtStartPar
Current limitations include:
\begin{itemize}
\item {} 
\sphinxAtStartPar
There are a number of tactics that are not yet supported in Ltac2 because
the interface OCaml and/or Ltac2 notations haven't been written.  See
{\hyperref[\detokenize{proof-engine/ltac2:defining-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Defining tactics}}}}.

\item {} 
\sphinxAtStartPar
Missing usability features such as:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Printing functions are limited and awkward to use.  Only a few data types are
printable.

\item {} 
\sphinxAtStartPar
Deep pattern matching and matching on tuples don't work.

\item {} 
\sphinxAtStartPar
A convenient way to build terms with casts through the low\sphinxhyphen{}level API. Because the
cast type is opaque, building terms with casts currently requires an awkward construction like the
following, which also incurs extra overhead to repeat typechecking for each
call to \sphinxcode{\sphinxupquote{get\_vm\_cast}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Constr}\PYG{o}{.}\PYG{n}{Unsafe}\PYG{o}{.}\PYG{n}{make} \PYG{o}{(}\PYG{n}{Constr}\PYG{o}{.}\PYG{n}{Unsafe}\PYG{o}{.}\PYG{n}{Cast} \PYG{k}{\PYGZsq{}}\PYG{n}{I} \PYG{o}{(}\PYG{n}{get\PYGZus{}vm\PYGZus{}cast} \PYG{n+nb+bp}{()}\PYG{o}{)} \PYG{k}{\PYGZsq{}}\PYG{n}{True}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
with:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Ltac2} \PYG{n}{get\PYGZus{}vm\PYGZus{}cast} \PYG{n+nb+bp}{()} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{Constr}\PYG{o}{.}\PYG{n}{Unsafe}\PYG{o}{.}\PYG{n}{kind} \PYG{k}{\PYGZsq{}}\PYG{o}{(}\PYG{n}{I} \PYG{o}{\PYGZlt{}}\PYG{o}{:} \PYG{n}{True}\PYG{o}{)} \PYG{k}{with}
  \PYG{o}{|} \PYG{n}{Constr}\PYG{o}{.}\PYG{n}{Unsafe}\PYG{o}{.}\PYG{n}{Cast} \PYG{o}{\PYGZus{}} \PYG{n}{cst} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{cst}
  \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{Control}\PYG{o}{.}\PYG{n}{throw} \PYG{n}{Not\PYGZus{}found}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\end{itemize}

\item {} 
\sphinxAtStartPar
Missing low\sphinxhyphen{}level primitives that are convenient for writing automation, such as:
\begin{itemize}
\item {} 
\sphinxAtStartPar
An easy way to get the number of constructors of an inductive type.
Currently only way to do this is to destruct a variable of the inductive type
and count the number of goals that result.

\end{itemize}

\item {} 
\sphinxAtStartPar
Error messages may be cryptic.

\end{itemize}


\subsubsection{General design}
\label{\detokenize{proof-engine/ltac2:general-design}}\label{\detokenize{proof-engine/ltac2:ltac2-design}}
\sphinxAtStartPar
There are various alternatives to Ltac1, such as Mtac or Rtac for instance.
While those alternatives can be quite different from Ltac1, we designed
Ltac2 to be as close as reasonably possible to Ltac1, while fixing the
aforementioned defects.

\sphinxAtStartPar
In particular, Ltac2 is:
\begin{itemize}
\item {} 
\sphinxAtStartPar
a member of the ML family of languages, i.e.
\begin{itemize}
\item {} 
\sphinxAtStartPar
a call\sphinxhyphen{}by\sphinxhyphen{}value functional language

\item {} 
\sphinxAtStartPar
with effects

\item {} 
\sphinxAtStartPar
together with the Hindley\sphinxhyphen{}Milner type system

\end{itemize}

\item {} 
\sphinxAtStartPar
a language featuring meta\sphinxhyphen{}programming facilities for the manipulation of
Coq\sphinxhyphen{}side terms

\item {} 
\sphinxAtStartPar
a language featuring notation facilities to help write palatable scripts

\end{itemize}

\sphinxAtStartPar
We describe these in more detail in the remainder of this document.


\subsubsection{ML component}
\label{\detokenize{proof-engine/ltac2:ml-component}}

\paragraph{Overview}
\label{\detokenize{proof-engine/ltac2:overview}}
\sphinxAtStartPar
Ltac2 is a member of the ML family of languages, in the sense that it is an
effectful call\sphinxhyphen{}by\sphinxhyphen{}value functional language, with static typing à la
Hindley\sphinxhyphen{}Milner (see {[}\hyperlink{cite.zebibliography:id54}{DM82}{]}). It is commonly accepted
that ML constitutes a sweet spot in PL design, as it is relatively expressive
while not being either too lax (unlike dynamic typing) nor too strict
(unlike, say, dependent types).

\sphinxAtStartPar
The main goal of Ltac2 is to serve as a meta\sphinxhyphen{}language for Coq. As such, it
naturally fits in the ML lineage, just as the historical ML was designed as
the tactic language for the LCF prover. It can also be seen as a general\sphinxhyphen{}purpose
language, by simply forgetting about the Coq\sphinxhyphen{}specific features.

\sphinxAtStartPar
Sticking to a standard ML type system can be considered somewhat weak for a
meta\sphinxhyphen{}language designed to manipulate Coq terms. In particular, there is no
way to statically guarantee that a Coq term resulting from an Ltac2
computation will be well\sphinxhyphen{}typed. This is actually a design choice, motivated
by backward compatibility with Ltac1. Instead, well\sphinxhyphen{}typedness is deferred to
dynamic checks, allowing many primitive functions to fail whenever they are
provided with an ill\sphinxhyphen{}typed term.

\sphinxAtStartPar
The language is naturally effectful as it manipulates the global state of the
proof engine. This allows to think of proof\sphinxhyphen{}modifying primitives as effects
in a straightforward way. Semantically, proof manipulation lives in a monad,
which allows to ensure that Ltac2 satisfies the same equations as a generic ML
with unspecified effects would do, e.g. function reduction is substitution
by a value.

\sphinxAtStartPar
Use the following command to import Ltac2:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{From} \PYG{n}{Ltac2} \PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Ltac2}\PYG{o}{.}
\end{sphinxVerbatim}


\paragraph{Type Syntax}
\label{\detokenize{proof-engine/ltac2:type-syntax}}
\sphinxAtStartPar
At the level of terms, we simply elaborate on Ltac1 syntax, which is quite
close to OCaml. Types follow the simply\sphinxhyphen{}typed syntax of OCaml.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type2}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type2}}}} \sphinxhyphen{}> {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type2}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type2}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_type2}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type2}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type2}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type1}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type1}}}} * \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type1}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type1}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type1}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type1}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_type1}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type1}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type1}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type0}}}} {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_type0}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type0}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} ) \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_typevar}]{\sphinxcrossref{\DUrole{hole}{ltac2\_typevar}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_typevar}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_typevar}]{\sphinxcrossref{\DUrole{hole}{ltac2\_typevar}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\textquotesingle{} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The set of base types can be extended thanks to the usual ML type
declarations such as algebraic datatypes and records.

\sphinxAtStartPar
Built\sphinxhyphen{}in types include:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{int}}, machine integers (size not specified, in practice inherited from OCaml)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{string}}, mutable strings

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{'a array}}, mutable arrays

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{exn}}, exceptions

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{constr}}, kernel\sphinxhyphen{}side terms

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{pattern}}, term patterns

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ident}}, well\sphinxhyphen{}formed identifiers

\end{itemize}


\paragraph{Type declarations}
\label{\detokenize{proof-engine/ltac2:type-declarations}}
\sphinxAtStartPar
One can define new types with the following commands.
\index{Ltac2 Type (command)@\spxentry{Ltac2 Type}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-Type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~Type~\DUrole{repeat-wrapper}{\DUrole{repeat}{rec}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_def}]{\sphinxcrossref{\DUrole{hole}{tac2typ\_def}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_def}]{\sphinxcrossref{\DUrole{hole}{tac2typ\_def}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2typ_def}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_def}]{\sphinxcrossref{\DUrole{hole}{tac2typ\_def}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_prm}]{\sphinxcrossref{\DUrole{hole}{tac2typ\_prm}}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{alternative}{\DUrole{alternative-block}{:=}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{::=}} {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_knd}]{\sphinxcrossref{\DUrole{hole}{tac2typ\_knd}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2typ_prm}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_prm}]{\sphinxcrossref{\DUrole{hole}{tac2typ\_prm}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_typevar}]{\sphinxcrossref{\DUrole{hole}{ltac2\_typevar}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_typevar}]{\sphinxcrossref{\DUrole{hole}{ltac2\_typevar}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2typ_knd}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_knd}]{\sphinxcrossref{\DUrole{hole}{tac2typ\_knd}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2alg_constructor}]{\sphinxcrossref{\DUrole{hole}{tac2alg\_constructor}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}}\DUrole{notation-sup}{?}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} .. {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2rec_field}]{\sphinxcrossref{\DUrole{hole}{tac2rec\_field}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{;}} \DUrole{repeat-wrapper}{\DUrole{repeat}{;}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2alg_constructor}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2alg_constructor}]{\sphinxcrossref{\DUrole{hole}{tac2alg\_constructor}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} ( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2rec_field}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2rec_field}]{\sphinxcrossref{\DUrole{hole}{tac2rec\_field}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{mutable}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{:=}}}}] \leavevmode
\sphinxAtStartPar
Defines a type with with an explicit set of constructors

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{::=}}}}] \leavevmode
\sphinxAtStartPar
Extends an existing open variant type, a special kind of variant type whose constructors are not
statically defined, but can instead be extended dynamically. A typical example
is the standard \sphinxcode{\sphinxupquote{exn}} type for exceptions. Pattern matching on open variants must always
include a catch\sphinxhyphen{}all clause. They can be extended with this form, in which case
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_knd}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tac2typ\_knd}}}}} should be in the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2alg_constructor}]{\sphinxcrossref{\DUrole{hole}{tac2alg\_constructor}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}}\DUrole{notation-sup}{?}} {]}}}}.

\item[{Without \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{:=}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{::=}}}}}}] \leavevmode
\sphinxAtStartPar
Defines an abstract type for use representing data from OCaml.  Not for
end users.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{with {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_def}]{\sphinxcrossref{\DUrole{hole}{tac2typ\_def}}}}}}}}] \leavevmode
\sphinxAtStartPar
Permits definition of mutually recursive type definitions.

\end{description}

\sphinxAtStartPar
Each production of {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2typ_knd}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tac2typ\_knd}}}}} defines one of four possible kinds
of definitions, respectively: alias, variant, open variant and record types.

\sphinxAtStartPar
Aliases are names for a given type expression and are transparently
unfoldable to that expression. They cannot be recursive.

\sphinxAtStartPar
Variants are sum types defined by constructors and eliminated by
pattern\sphinxhyphen{}matching. They can be recursive, but the \sphinxcode{\sphinxupquote{rec}} flag must be
explicitly set. Pattern matching must be exhaustive.

\sphinxAtStartPar
Open variants can be extended with additional constructors using the \sphinxcode{\sphinxupquote{::=}} form.

\sphinxAtStartPar
Records are product types with named fields and eliminated by projection.
Likewise they can be recursive if the \sphinxcode{\sphinxupquote{rec}} flag is set.

\end{fulllineitems}\end{savenotes}

\index{Ltac2 external (command)@\spxentry{Ltac2 external}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-external}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~@~external~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}~:=~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
Declares abstract terms.  Frequently, these declare OCaml functions
defined in Coq and give their type information.  They can also declare
data structures from OCaml.  This command has no use for the end user.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{using/libraries/writing:coq:attr.deprecated}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{deprecated}}}}} attribute.

\end{fulllineitems}\end{savenotes}



\paragraph{APIs}
\label{\detokenize{proof-engine/ltac2:apis}}
\sphinxAtStartPar
Ltac2 provides over 150 API functions that provide various capabilities.  These
are declared with {\hyperref[\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-external}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac2 external}}}}} in \sphinxcode{\sphinxupquote{\DUrole{notation}{lib/coq/user\sphinxhyphen{}contrib/Ltac2/*.v}}}.
For example, \sphinxcode{\sphinxupquote{Message.print}} defined in \sphinxcode{\sphinxupquote{Message.v}} is used to print messages:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Message}\PYG{o}{.}\PYG{n}{print} \PYG{o}{(}\PYG{n}{Message}\PYG{o}{.}\PYG{n}{of\PYGZus{}string} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{fully qualified calls}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{fully} \PYG{n}{qualified} \PYG{n}{calls}

\PYG{n}{From} \PYG{n}{Ltac2} \PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Message}\PYG{o}{.}
\PYG{n}{print} \PYG{o}{(}\PYG{n}{of\PYGZus{}string} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{unqualified calls}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{unqualified} \PYG{n}{calls}
\end{sphinxVerbatim}


\paragraph{Term Syntax}
\label{\detokenize{proof-engine/ltac2:term-syntax}}
\sphinxAtStartPar
The syntax of the functional fragment is very close to that of Ltac1, except
that it adds a true pattern\sphinxhyphen{}matching feature, as well as a few standard
constructs from ML.

\sphinxAtStartPar
In practice, there is some additional syntactic sugar that allows the
user to bind a variable and match on it at the same time, in the usual ML style.

\sphinxAtStartPar
There is dedicated syntax for list and array literals.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5}}}} ; {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\DUrole{hole}{tac2pat0}}}}}\DUrole{notation-sup}{+}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}\DUrole{notation-sup}{?}} => {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{let \DUrole{repeat-wrapper}{\DUrole{repeat}{rec}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_let_clause}]{\sphinxcrossref{\DUrole{hole}{ltac2\_let\_clause}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_let_clause}]{\sphinxcrossref{\DUrole{hole}{ltac2\_let\_clause}}}}}\DUrole{notation-sup}{*}} in {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr3}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_let_clause}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_let_clause}]{\sphinxcrossref{\DUrole{hole}{ltac2\_let\_clause}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\DUrole{hole}{tac2pat0}}}}}\DUrole{notation-sup}{+}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr3}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr3}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr3}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr2}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr2}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr2}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr1}}}} :: {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr2}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr2}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr1}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr1}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr1}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr0}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr0}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr0}}}} .( {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr0}}}} .( {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} ) := {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2rec_fieldexpr}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2rec_fieldexpr}]{\sphinxcrossref{\DUrole{hole}{tac2rec\_fieldexpr}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} := {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr1}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr1}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr0}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr0}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr0}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}} : {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{()}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\{ \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2rec_fieldexpr}]{\sphinxcrossref{\DUrole{hole}{tac2rec\_fieldexpr}}}}}\DUrole{notation-sup}{+}} \DUrole{repeat-wrapper}{\DUrole{repeat}{;}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}} \}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_tactic_atom}]{\sphinxcrossref{\DUrole{hole}{ltac2\_tactic\_atom}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_tactic_atom}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_tactic_atom}]{\sphinxcrossref{\DUrole{hole}{ltac2\_tactic\_atom}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{@ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\& {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\textquotesingle{} {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_quotations}]{\sphinxcrossref{\DUrole{hole}{ltac2\_quotations}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The non\sphinxhyphen{}terminal \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-lident}}\sphinxcode{\sphinxupquote{lident}}} designates identifiers starting with a
lowercase letter.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\textquotesingle{}{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{open\_constr:({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}.


\paragraph{Ltac2 Definitions}
\label{\detokenize{proof-engine/ltac2:ltac2-definitions}}\index{Ltac2 (command)@\spxentry{Ltac2}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:cmd.Ltac2}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~\DUrole{repeat-wrapper}{\DUrole{repeat}{mutable}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{rec}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2def_body}]{\sphinxcrossref{\DUrole{hole}{tac2def\_body}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2def_body}]{\sphinxcrossref{\DUrole{hole}{tac2def\_body}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2def_body}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2def_body}]{\sphinxcrossref{\DUrole{hole}{tac2def\_body}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{\_}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\DUrole{hole}{tac2pat0}}}}}\DUrole{notation-sup}{*}} \DUrole{repeat-wrapper}{\DUrole{repeat}{: {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}\DUrole{notation-sup}{?}} := {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
This command defines a new global Ltac2 value.  If one or more {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tac2pat0}}}}}
are specified, the new value is a function.  This is a shortcut for one of the
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr5}}}}} productions.  For example: \sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 foo a b := …}}} is equivalent
to \sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 foo := fun a b => …}}}.

\sphinxAtStartPar
The body of an Ltac2 definition is required to be a syntactical value
that is, a function, a constant, a pure constructor recursively applied to
values or a (non\sphinxhyphen{}recursive) let binding of a value in a value.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{rec}} is set, the tactic is expanded into a recursive binding.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{mutable}} is set, the definition can be redefined at a later stage (see below).

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{using/libraries/writing:coq:attr.deprecated}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{deprecated}}}}} attribute.

\end{fulllineitems}\end{savenotes}

\index{Ltac2 Set (command)@\spxentry{Ltac2 Set}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-Set}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~Set~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}}}
\sphinxAtStartPar
This command redefines a previous \sphinxcode{\sphinxupquote{mutable}} definition.
Mutable definitions act like dynamic binding, i.e. at runtime, the last defined
value for this entry is chosen. This is useful for global flags and the like.
The previous value of the binding can be optionally accessed using the \sphinxcode{\sphinxupquote{as}}
binding syntax.

\begin{sphinxadmonition}{note}{Example: Dynamic nature of mutable cells}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Ltac2} \PYG{n}{mutable} \PYG{n}{x} \PYG{o}{:=} \PYG{n+nb+bp}{true}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{n}{y} \PYG{o}{:=} \PYG{n}{x}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{n}{Eval} \PYG{n}{y}\PYG{o}{.}
    \PYG{o}{\PYGZhy{}} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{=} \PYG{n+nb+bp}{true}

\PYG{n}{Ltac2} \PYG{k+kn}{Set} \PYG{n}{x} \PYG{o}{:=} \PYG{n+nb+bp}{false}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{n}{Eval} \PYG{n}{y}\PYG{o}{.}
    \PYG{o}{\PYGZhy{}} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{=} \PYG{n+nb+bp}{false}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: Interaction with recursive calls}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Ltac2} \PYG{n}{mutable} \PYG{n}{rec} \PYG{n}{f} \PYG{n}{b} \PYG{o}{:=} \PYG{k}{if} \PYG{n}{b} \PYG{k}{then} \PYG{l+m+mi}{0} \PYG{k}{else} \PYG{n}{f} \PYG{n+nb+bp}{true}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{k+kn}{Set} \PYG{n}{f} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{b} \PYG{o}{=\PYGZgt{}} \PYG{k}{if} \PYG{n}{b} \PYG{k}{then} \PYG{l+m+mi}{1} \PYG{k}{else} \PYG{n}{f} \PYG{n+nb+bp}{true}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{n}{Eval} \PYG{o}{(}\PYG{n}{f} \PYG{n+nb+bp}{false}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZhy{}} \PYG{o}{:} \PYG{n}{int} \PYG{o}{=} \PYG{l+m+mi}{1}

\PYG{n}{Ltac2} \PYG{k+kn}{Set} \PYG{n}{f} \PYG{k}{as} \PYG{n}{oldf} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{b} \PYG{o}{=\PYGZgt{}} \PYG{k}{if} \PYG{n}{b} \PYG{k}{then}  \PYG{l+m+mi}{2} \PYG{k}{else} \PYG{n}{oldf} \PYG{n+nb+bp}{false}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{n}{Eval} \PYG{o}{(}\PYG{n}{f} \PYG{n+nb+bp}{false}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZhy{}} \PYG{o}{:} \PYG{n}{int} \PYG{o}{=} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}

\sphinxAtStartPar
In the definition, the \sphinxcode{\sphinxupquote{f}} in the body is resolved statically
because the definition is marked recursive. In the first re\sphinxhyphen{}definition,
the \sphinxcode{\sphinxupquote{f}} in the body is resolved dynamically. This is witnessed by
the second re\sphinxhyphen{}definition.
\end{sphinxadmonition}

\end{fulllineitems}\end{savenotes}



\paragraph{Reduction}
\label{\detokenize{proof-engine/ltac2:reduction}}
\sphinxAtStartPar
We use the usual ML call\sphinxhyphen{}by\sphinxhyphen{}value reduction, with an otherwise unspecified
evaluation order. This is a design choice making it compatible with OCaml,
if ever we implement native compilation. The expected equations are as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(fun x =\PYGZgt{} t) V ≡ t\PYGZob{}x := V\PYGZcb{} (βv)

let x := V in t ≡ t\PYGZob{}x := V\PYGZcb{} (let)

match C V₀ ... Vₙ with ... | C x₀ ... xₙ  =\PYGZgt{} t | ... end ≡ t \PYGZob{}xᵢ := Vᵢ\PYGZcb{} (ι)

(t any term, V values, C constructor)
\end{sphinxVerbatim}

\sphinxAtStartPar
Note that call\sphinxhyphen{}by\sphinxhyphen{}value reduction is already a departure from Ltac1 which uses
heuristics to decide when to evaluate an expression. For instance, the following
expressions do not evaluate the same way in Ltac1.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{foo (idtac; let x := 0 in bar)}}}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{foo (let x := 0 in bar)}}}

\sphinxAtStartPar
Instead of relying on the \sphinxcode{\sphinxupquote{\DUrole{notation}{idtac}}} idiom, we would now require an explicit thunk
to not compute the argument, and \sphinxcode{\sphinxupquote{\DUrole{notation}{foo}}} would have e.g. type
\sphinxcode{\sphinxupquote{\DUrole{notation}{(unit \sphinxhyphen{}> unit) \sphinxhyphen{}> unit}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{foo (fun () => let x := 0 in bar)}}}


\paragraph{Typing}
\label{\detokenize{proof-engine/ltac2:typing}}
\sphinxAtStartPar
Typing is strict and follows the Hindley\sphinxhyphen{}Milner system. Unlike Ltac1, there
are no type casts at runtime, and one has to resort to conversion
functions. See notations though to make things more palatable.

\sphinxAtStartPar
In this setting, all the usual argument\sphinxhyphen{}free tactics have type \sphinxcode{\sphinxupquote{\DUrole{notation}{unit \sphinxhyphen{}> unit}}}, but
one can return a value of type \sphinxcode{\sphinxupquote{\DUrole{notation}{t}}} thanks to terms of type \sphinxcode{\sphinxupquote{\DUrole{notation}{unit \sphinxhyphen{}> t}}},
or take additional arguments.


\paragraph{Effects}
\label{\detokenize{proof-engine/ltac2:effects}}
\sphinxAtStartPar
Effects in Ltac2 are straightforward, except that instead of using the
standard IO monad as the ambient effectful world, Ltac2 is has a
tactic monad.

\sphinxAtStartPar
Note that the order of evaluation of application is \sphinxstyleemphasis{not} specified and is
implementation\sphinxhyphen{}dependent, as in OCaml.

\sphinxAtStartPar
We recall that the \sphinxcode{\sphinxupquote{Proofview.tactic}} monad is essentially a IO monad together
with backtracking state representing the proof state.

\sphinxAtStartPar
Intuitively a thunk of type \sphinxcode{\sphinxupquote{\DUrole{notation}{unit \sphinxhyphen{}> \textquotesingle{}a}}} can do the following:
\begin{itemize}
\item {} 
\sphinxAtStartPar
It can perform non\sphinxhyphen{}backtracking IO like printing and setting mutable variables

\item {} 
\sphinxAtStartPar
It can fail in a non\sphinxhyphen{}recoverable way

\item {} 
\sphinxAtStartPar
It can use first\sphinxhyphen{}class backtracking. One way to think about this is that
thunks are isomorphic to this type:
\sphinxcode{\sphinxupquote{\DUrole{notation}{(unit \sphinxhyphen{}> \textquotesingle{}a) \textasciitilde{} (unit \sphinxhyphen{}> exn + (\textquotesingle{}a * (exn \sphinxhyphen{}> \textquotesingle{}a)))}}}
i.e. thunks can produce a lazy list of results where each
tail is waiting for a continuation exception.

\item {} 
\sphinxAtStartPar
It can access a backtracking proof state, consisting among other things of
the current evar assignment and the list of goals under focus.

\end{itemize}

\sphinxAtStartPar
We now describe more thoroughly the various effects in Ltac2.


\subparagraph{Standard IO}
\label{\detokenize{proof-engine/ltac2:standard-io}}
\sphinxAtStartPar
The Ltac2 language features non\sphinxhyphen{}backtracking IO, notably mutable data and
printing operations.

\sphinxAtStartPar
Mutable fields of records can be modified using the set syntax. Likewise,
built\sphinxhyphen{}in types like \sphinxcode{\sphinxupquote{string}} and \sphinxcode{\sphinxupquote{array}} feature imperative assignment. See
modules \sphinxcode{\sphinxupquote{String}} and \sphinxcode{\sphinxupquote{Array}} respectively.

\sphinxAtStartPar
A few printing primitives are provided in the \sphinxcode{\sphinxupquote{Message}} module for
displaying information to the user.


\subparagraph{Fatal errors}
\label{\detokenize{proof-engine/ltac2:fatal-errors}}
\sphinxAtStartPar
The Ltac2 language provides non\sphinxhyphen{}backtracking exceptions, also known as \sphinxstyleemphasis{panics},
through the following primitive in module \sphinxcode{\sphinxupquote{Control}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
val throw : exn \PYGZhy{}\PYGZgt{} \PYGZsq{}a
\end{sphinxVerbatim}

\sphinxAtStartPar
Unlike backtracking exceptions from the next section, this kind of error
is never caught by backtracking primitives, that is, throwing an exception
destroys the stack. This is codified by the following equation, where \sphinxcode{\sphinxupquote{E}}
is an evaluation context:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
E[throw e] ≡ throw e

(e value)
\end{sphinxVerbatim}

\sphinxAtStartPar
There is currently no way to catch such an exception, which is a deliberate design choice.
Eventually there might be a way to catch it and
destroy all backtrack and return values.


\subparagraph{Backtracking}
\label{\detokenize{proof-engine/ltac2:backtracking}}
\sphinxAtStartPar
In Ltac2, we have the following backtracking primitives, defined in the
\sphinxcode{\sphinxupquote{Control}} module:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Ltac2 Type \PYGZsq{}a result := [ Val (\PYGZsq{}a) | Err (exn) ].

val zero : exn \PYGZhy{}\PYGZgt{} \PYGZsq{}a
val plus : (unit \PYGZhy{}\PYGZgt{} \PYGZsq{}a) \PYGZhy{}\PYGZgt{} (exn \PYGZhy{}\PYGZgt{} \PYGZsq{}a) \PYGZhy{}\PYGZgt{} \PYGZsq{}a
val case : (unit \PYGZhy{}\PYGZgt{} \PYGZsq{}a) \PYGZhy{}\PYGZgt{} (\PYGZsq{}a * (exn \PYGZhy{}\PYGZgt{} \PYGZsq{}a)) result
\end{sphinxVerbatim}

\sphinxAtStartPar
If one views thunks as lazy lists, then \sphinxcode{\sphinxupquote{zero}} is the empty list and \sphinxcode{\sphinxupquote{plus}} is
list concatenation, while \sphinxcode{\sphinxupquote{case}} is pattern\sphinxhyphen{}matching.

\sphinxAtStartPar
The backtracking is first\sphinxhyphen{}class, i.e. one can write
\sphinxcode{\sphinxupquote{\DUrole{notation}{plus (fun () => "x") (fun \_ => "y") : string}}} producing a backtracking string.

\sphinxAtStartPar
These operations are expected to satisfy a few equations, most notably that they
form a monoid compatible with sequentialization.:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
plus t zero ≡ t ()
plus (fun () =\PYGZgt{} zero e) f ≡ f e
plus (plus t f) g ≡ plus t (fun e =\PYGZgt{} plus (f e) g)

case (fun () =\PYGZgt{} zero e) ≡ Err e
case (fun () =\PYGZgt{} plus (fun () =\PYGZgt{} t) f) ≡ Val (t,f)

let x := zero e in u ≡ zero e
let x := plus t f in u ≡ plus (fun () =\PYGZgt{} let x := t in u) (fun e =\PYGZgt{} let x := f e in u)

(t, u, f, g, e values)
\end{sphinxVerbatim}


\subparagraph{Goals}
\label{\detokenize{proof-engine/ltac2:goals}}
\sphinxAtStartPar
A goal is given by the data of its conclusion and hypotheses, i.e. it can be
represented as \sphinxcode{\sphinxupquote{{[}Γ ⊢ A{]}}}.

\sphinxAtStartPar
The tactic monad naturally operates over the whole proofview, which may
represent several goals, including none. Thus, there is no such thing as
\sphinxstyleemphasis{the current goal}. Goals are naturally ordered, though.

\sphinxAtStartPar
It is natural to do the same in Ltac2, but we must provide a way to get access
to a given goal. This is the role of the \sphinxcode{\sphinxupquote{enter}} primitive, which applies a
tactic to each currently focused goal in turn:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
val enter : (unit \PYGZhy{}\PYGZgt{} unit) \PYGZhy{}\PYGZgt{} unit
\end{sphinxVerbatim}

\sphinxAtStartPar
It is guaranteed that when evaluating \sphinxcode{\sphinxupquote{enter f}}, \sphinxcode{\sphinxupquote{f}} is called with exactly one
goal under focus. Note that \sphinxcode{\sphinxupquote{f}} may be called several times, or never, depending
on the number of goals under focus before the call to \sphinxcode{\sphinxupquote{enter}}.

\sphinxAtStartPar
Accessing the goal data is then implicit in the Ltac2 primitives, and may panic
if the invariants are not respected. The two essential functions for observing
goals are given below.:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
val hyp : ident \PYGZhy{}\PYGZgt{} constr
val goal : unit \PYGZhy{}\PYGZgt{} constr
\end{sphinxVerbatim}

\sphinxAtStartPar
The two above functions panic if there is not exactly one goal under focus.
In addition, \sphinxcode{\sphinxupquote{hyp}} may also fail if there is no hypothesis with the
corresponding name.


\subsubsection{Meta\sphinxhyphen{}programming}
\label{\detokenize{proof-engine/ltac2:meta-programming}}

\paragraph{Overview}
\label{\detokenize{proof-engine/ltac2:id3}}
\sphinxAtStartPar
One of the major implementation issues of Ltac1 is the fact that it is
never clear whether an object refers to the object world or the meta\sphinxhyphen{}world.
This is an incredible source of slowness, as the interpretation must be
aware of bound variables and must use heuristics to decide whether a variable
is a proper one or referring to something in the Ltac context.

\sphinxAtStartPar
Likewise, in Ltac1, constr parsing is implicit, so that \sphinxcode{\sphinxupquote{foo 0}} is
not \sphinxcode{\sphinxupquote{foo}} applied to the Ltac integer expression \sphinxcode{\sphinxupquote{0}} (\sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$ does have a
notion of integers, though it is not first\sphinxhyphen{}class), but rather the Coq term
\sphinxcode{\sphinxupquote{\DUrole{name}{Datatypes}\DUrole{operator}{.}\DUrole{name}{O}}}.

\sphinxAtStartPar
The implicit parsing is confusing to users and often gives unexpected results.
Ltac2 makes these explicit using quoting and unquoting notation, although there
are notations to do it in a short and elegant way so as not to be too cumbersome
to the user.


\paragraph{Quotations}
\label{\detokenize{proof-engine/ltac2:quotations}}

\subparagraph{Built\sphinxhyphen{}in quotations}
\label{\detokenize{proof-engine/ltac2:built-in-quotations}}\label{\detokenize{proof-engine/ltac2:ltac2-built-in-quotations}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_quotations}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_quotations}]{\sphinxcrossref{\DUrole{hole}{ltac2\_quotations}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ident : ( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{constr : ( {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{open\_constr : ( {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{pat : ( {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{reference : ( \DUrole{alternative}{\DUrole{alternative-block}{\& {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ltac1 : ( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac1_expr_in_env}]{\sphinxcrossref{\DUrole{hole}{ltac1\_expr\_in\_env}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ltac1val : ( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac1_expr_in_env}]{\sphinxcrossref{\DUrole{hole}{ltac1\_expr\_in\_env}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac1_expr_in_env}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac1_expr_in_env}]{\sphinxcrossref{\DUrole{hole}{ltac1\_expr\_in\_env}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}} |\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The current implementation recognizes the following built\sphinxhyphen{}in quotations:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ident}}, which parses identifiers (type \sphinxcode{\sphinxupquote{Init.ident}}).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{constr}}, which parses Coq terms and produces an\sphinxhyphen{}evar free term at runtime
(type \sphinxcode{\sphinxupquote{Init.constr}}).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{open\_constr}}, which parses Coq terms and produces a term potentially with
holes at runtime (type \sphinxcode{\sphinxupquote{Init.constr}} as well).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{pat}}, which parses Coq patterns and produces a pattern used for term
matching (type \sphinxcode{\sphinxupquote{Init.pattern}}).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{reference}}  Qualified names
are globalized at internalization into the corresponding global reference,
while \sphinxcode{\sphinxupquote{\&id}} is turned into \sphinxcode{\sphinxupquote{Std.VarRef id}}. This produces at runtime a
\sphinxcode{\sphinxupquote{Std.reference}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ltac1}}, for calling Ltac1 code, described in {\hyperref[\detokenize{proof-engine/ltac2:simple-api}]{\sphinxcrossref{\DUrole{std,std-ref}{Simple API}}}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ltac1val}}, for manipulating Ltac1 values, described in {\hyperref[\detokenize{proof-engine/ltac2:low-level-api}]{\sphinxcrossref{\DUrole{std,std-ref}{Low\sphinxhyphen{}level API}}}}.

\end{itemize}

\sphinxAtStartPar
The following syntactic sugar is provided for two common cases:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{@id}} is the same as \sphinxcode{\sphinxupquote{ident:(id)}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\textquotesingle{}{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{open\_constr:({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}

\end{itemize}


\subparagraph{Strict vs. non\sphinxhyphen{}strict mode}
\label{\detokenize{proof-engine/ltac2:strict-vs-non-strict-mode}}
\sphinxAtStartPar
Depending on the context, quotation\sphinxhyphen{}producing terms (i.e. \sphinxcode{\sphinxupquote{constr}} or
\sphinxcode{\sphinxupquote{open\_constr}}) are not internalized in the same way. There are two possible
modes, the \sphinxstyleemphasis{strict} and the \sphinxstyleemphasis{non\sphinxhyphen{}strict} mode.
\begin{itemize}
\item {} 
\sphinxAtStartPar
In strict mode, all simple identifiers appearing in a term quotation are
required to be resolvable statically. That is, they must be the short name of
a declaration which is defined globally, excluding section variables and
hypotheses. If this doesn't hold, internalization will fail. To work around
this error, one has to specifically use the \sphinxcode{\sphinxupquote{\&}} notation.

\item {} 
\sphinxAtStartPar
In non\sphinxhyphen{}strict mode, any simple identifier appearing in a term quotation which
is not bound in the global environment is turned into a dynamic reference to a
hypothesis. That is to say, internalization will succeed, but the evaluation
of the term at runtime will fail if there is no such variable in the dynamic
context.

\end{itemize}

\sphinxAtStartPar
Strict mode is enforced by default, such as for all Ltac2 definitions. Non\sphinxhyphen{}strict
mode is only set when evaluating Ltac2 snippets in interactive proof mode. The
rationale is that it is cumbersome to explicitly add \sphinxcode{\sphinxupquote{\&}} interactively, while it
is expected that global tactics enforce more invariants on their code.


\paragraph{Term Antiquotations}
\label{\detokenize{proof-engine/ltac2:term-antiquotations}}

\subparagraph{Syntax}
\label{\detokenize{proof-engine/ltac2:syntax}}
\sphinxAtStartPar
One can also insert Ltac2 code into Coq terms, similar to what is possible in
Ltac1.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ltac2:( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Antiquoted terms are expected to have type \sphinxcode{\sphinxupquote{unit}}, as they are only evaluated
for their side\sphinxhyphen{}effects.


\subparagraph{Semantics}
\label{\detokenize{proof-engine/ltac2:semantics}}
\sphinxAtStartPar
A quoted Coq term is interpreted in two phases, internalization and
evaluation.
\begin{itemize}
\item {} 
\sphinxAtStartPar
Internalization is part of the static semantics, that is, it is done at Ltac2
typing time.

\item {} 
\sphinxAtStartPar
Evaluation is part of the dynamic semantics, that is, it is done when
a term gets effectively computed by Ltac2.

\end{itemize}

\sphinxAtStartPar
Note that typing of Coq terms is a \sphinxstyleemphasis{dynamic} process occurring at Ltac2
evaluation time, and not at Ltac2 typing time.


\subparagraph{Static semantics}
\label{\detokenize{proof-engine/ltac2:static-semantics}}
\sphinxAtStartPar
During internalization, Coq variables are resolved and antiquotations are
type checked as Ltac2 terms, effectively producing a \sphinxcode{\sphinxupquote{glob\_constr}} in Coq
implementation terminology. Note that although it went through the
type checking of \sphinxstylestrong{Ltac2}, the resulting term has not been fully computed and
is potentially ill\sphinxhyphen{}typed as a runtime \sphinxstylestrong{Coq} term.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The following term is valid (with type \sphinxcode{\sphinxupquote{unit \sphinxhyphen{}> constr}}), but will fail at runtime:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Ltac2} \PYG{n}{myconstr} \PYG{n+nb+bp}{()} \PYG{o}{:=} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Term antiquotations are type checked in the enclosing Ltac2 typing context
of the corresponding term expression.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The following will type check, with type \sphinxcode{\sphinxupquote{constr}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{let} \PYG{n}{x} \PYG{o}{:=} \PYG{k}{\PYGZsq{}}\PYG{l+m+mi}{0} \PYG{k}{in} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{ltac2}\PYG{o}{:}\PYG{o}{(}\PYG{k+kp}{exact} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Beware that the typing environment of antiquotations is \sphinxstylestrong{not}
expanded by the Coq binders from the term.
\begin{quote}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The following Ltac2 expression will \sphinxstylestrong{not} type check:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
`constr:(fun x : nat =\PYGZgt{} ltac2:(exact x))`
`(* Error: Unbound variable \PYGZsq{}x\PYGZsq{} *)`
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}

\sphinxAtStartPar
There is a simple reason for that, which is that the following expression would
not make sense in general.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{constr:(fun x : nat => ltac2:(clear @x; exact x))}}

\sphinxAtStartPar
Indeed, a hypothesis can suddenly disappear from the runtime context if some
other tactic pulls the rug from under you.

\sphinxAtStartPar
Rather, the tactic writer has to resort to the \sphinxstylestrong{dynamic} goal environment,
and must write instead explicitly that she is accessing a hypothesis, typically
as follows.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{constr:(fun x : nat => ltac2:(exact (hyp @x)))}}

\sphinxAtStartPar
This pattern is so common that we provide dedicated Ltac2 and Coq term notations
for it.
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\&x}} as an Ltac2 expression expands to \sphinxcode{\sphinxupquote{hyp @x}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\&x}} as a Coq constr expression expands to
\sphinxcode{\sphinxupquote{ltac2:(Control.refine (fun () => hyp @x))}}.

\end{itemize}

\sphinxAtStartPar
In the special case where Ltac2 antiquotations appear inside a Coq term
notation, the notation variables are systematically bound in the body
of the tactic expression with type \sphinxcode{\sphinxupquote{Ltac2.Init.preterm}}. Such a type represents
untyped syntactic Coq expressions, which can by typed in the
current context using the \sphinxcode{\sphinxupquote{Ltac2.Constr.pretype}} function.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The following notation is essentially the identity.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[ x ]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{ltac2}\PYG{o}{:}\PYG{o}{(}\PYG{k}{let} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{Ltac2}\PYG{o}{.}\PYG{n}{Constr}\PYG{o}{.}\PYG{n}{pretype} \PYG{n}{x} \PYG{k}{in} \PYG{k+kp}{exact} \PYG{o}{\PYGZdl{}}\PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subparagraph{Dynamic semantics}
\label{\detokenize{proof-engine/ltac2:dynamic-semantics}}
\sphinxAtStartPar
During evaluation, a quoted term is fully evaluated to a kernel term, and is
in particular type checked in the current environment.

\sphinxAtStartPar
Evaluation of a quoted term goes as follows.
\begin{itemize}
\item {} 
\sphinxAtStartPar
The quoted term is first evaluated by the pretyper.

\item {} 
\sphinxAtStartPar
Antiquotations are then evaluated in a context where there is exactly one goal
under focus, with the hypotheses coming from the current environment extended
with the bound variables of the term, and the resulting term is fed into the
quoted term.

\end{itemize}

\sphinxAtStartPar
Relative orders of evaluation of antiquotations and quoted term are not
specified.

\sphinxAtStartPar
For instance, in the following example, \sphinxcode{\sphinxupquote{tac}} will be evaluated in a context
with exactly one goal under focus, whose last hypothesis is \sphinxcode{\sphinxupquote{H : nat}}. The
whole expression will thus evaluate to the term \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{H} \DUrole{operator}{:} \DUrole{name}{nat} \DUrole{operator}{=>} \DUrole{name}{H}}}.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{let tac () := hyp @H in constr:(fun H : nat => ltac2:(tac ()))}}

\sphinxAtStartPar
Many standard tactics perform type checking of their argument before going
further. It is your duty to ensure that terms are well\sphinxhyphen{}typed when calling
such tactics. Failure to do so will result in non\sphinxhyphen{}recoverable exceptions.

\sphinxAtStartPar
\sphinxstylestrong{Trivial Term Antiquotations}

\sphinxAtStartPar
It is possible to refer to a variable of type \sphinxcode{\sphinxupquote{constr}} in the Ltac2 environment
through a specific syntax consistent with the antiquotations presented in
the notation section.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-term}}}\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\${\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
In a Coq term, writing \sphinxcode{\sphinxupquote{\DUrole{operator}{\$}\DUrole{name}{x}}} is semantically equivalent to
\sphinxcode{\sphinxupquote{\DUrole{name}{ltac2}\DUrole{operator}{:(}\DUrole{name}{Control}\DUrole{operator}{.}\DUrole{keyword}{refine} \DUrole{operator}{(}\DUrole{keyword}{fun} \DUrole{name,builtin,pseudo}{()} \DUrole{operator}{=>} \DUrole{name}{x}\DUrole{operator}{))}}}, up to re\sphinxhyphen{}typechecking. It allows to
insert in a concise way an Ltac2 variable of type \sphinxcode{\sphinxupquote{\DUrole{notation}{constr}}} into a Coq term.


\paragraph{Match over terms}
\label{\detokenize{proof-engine/ltac2:match-over-terms}}
\sphinxAtStartPar
Ltac2 features a construction similar to Ltac1 {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} over terms, although
in a less hard\sphinxhyphen{}wired way.
\index{lazy\_match"! (tactic)@\spxentry{lazy\_match"!}\spxextra{tactic}}\index{match"! (tactic)@\spxentry{match"!}\spxextra{tactic}}\index{multi\_match"! (tactic)@\spxentry{multi\_match"!}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:tacn.lazy_match!}}\phantomsection\label{\detokenize{proof-engine/ltac2:coq:tacn.match!}}\phantomsection\label{\detokenize{proof-engine/ltac2:coq:tacn.multi_match!}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_key}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_key}}}}~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr$_{\text{term}}$}}}}~with~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_list}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_list}}}}~end}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_key}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_key}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_key}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{lazy\_match!}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{match!}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{multi\_match!}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_list}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_list}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_list}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_rule}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_rule}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_rule}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_rule}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_rule}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_pattern}}}} => {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{context \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Evaluates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr$_{\text{term}}$}}}}}}}, which must yield a term, and matches it
sequentially with the {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_match\_pattern}}}}}s, which may contain
metavariables.  When a match is found, metavariable values are substituted
into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}}, which is then applied.

\sphinxAtStartPar
Matching may continue depending on whether  \sphinxcode{\sphinxupquote{lazy\_match!}}, \sphinxcode{\sphinxupquote{match!}} or \sphinxcode{\sphinxupquote{multi\_match!}}
is specified.

\sphinxAtStartPar
In the {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_match\_pattern}}}}}s, metavariables have the form \sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, whereas
in the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}}s, the question mark is omitted.

\sphinxAtStartPar
Matching is non\sphinxhyphen{}linear: if a
metavariable occurs more than once, each occurrence must match the same
expression.  Expressions match if they are syntactically equal or are
{\hyperref[\detokenize{language/core/conversion:term-alpha-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{α\sphinxhyphen{}convertible}}}}.
Matching is first\sphinxhyphen{}order except on variables of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{@?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
that occur in the head position of an application. For these variables,
matching is second\sphinxhyphen{}order and returns a functional term.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{lazy\_match!}}}] \leavevmode
\sphinxAtStartPar
Causes the match to commit to the first matching branch
rather than trying a new match if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} fails.
{\hyperref[\detokenize{proof-engine/ltac2:ltac2-match-vs-lazymatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\item[{\sphinxcode{\sphinxupquote{match!}}}] \leavevmode
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} fails, continue matching with the next branch.
Failures in subsequent tactics (after the \sphinxcode{\sphinxupquote{match!}}) will not cause selection
of a new branch.  Examples {\hyperref[\detokenize{proof-engine/ltac2:ltac2-match-vs-lazymatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}} and
{\hyperref[\detokenize{proof-engine/ltac2:ltac2-match-vs-multimatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\item[{\sphinxcode{\sphinxupquote{multi\_match!}}}] \leavevmode
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} fails, continue matching with the next branch.
When a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} succeeds for a branch, subsequent failures
(after the \sphinxcode{\sphinxupquote{multi\_match!}}) causing consumption of all the successes
of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} trigger selection of a new matching branch.
{\hyperref[\detokenize{proof-engine/ltac2:ltac2-match-vs-multimatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}}}}}}] \leavevmode
\sphinxAtStartPar
The syntax of {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cpattern}}}}} is
the same as that of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}s, but it can contain pattern matching
metavariables in the form \sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{@?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.  \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}} can be used to match
irrelevant terms.

\sphinxAtStartPar
Unlike Ltac1, Ltac2 \sphinxcode{\sphinxupquote{\DUrole{notation}{?id}}} metavariables only match closed terms.

\sphinxAtStartPar
There is also a special notation for second\sphinxhyphen{}order pattern matching: in an
applicative pattern of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{@?{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} … {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{n}}$}}}}}}},
the variable {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} matches any complex expression with (possible)
dependencies in the variables \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}} and returns a functional term
of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{fun {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} … {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{n}}$}}}} => {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{description}
\phantomsection\label{\detokenize{proof-engine/ltac2:match-term-context}}\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{context \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}} {]}}}}}] \leavevmode
\sphinxAtStartPar
Matches any term with a subterm matching {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cpattern}}}}}. If there is a match
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is present, it is assigned the "matched
context", i.e. the initial term where the matched subterm is replaced by a
hole.  This hole in the matched context can be filled with the expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{Pattern.instantiate {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\DUrole{hole}{cpattern}}}}}}}.

\sphinxAtStartPar
For {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match!}}}}} and {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.multi_match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multi\_match!}}}}}, if the evaluation of the {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr}}}}}
fails, the next matching subterm is tried. If no further subterm matches, the next branch
is tried.  Matching subterms are considered from top to bottom and from left to
right (with respect to the raw printing obtained by setting the
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} flag).  {\hyperref[\detokenize{proof-engine/ltac2:ltac2-match-term-context-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\end{description}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}}}] \leavevmode
\sphinxAtStartPar
The tactic to apply if the construct matches.  Metavariable values from the pattern
match are statically bound as Ltac2 variables in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} before
it is applied.

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} is a tactic with backtracking points, then subsequent
failures after a {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.lazy_match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazy\_match!}}}}} or {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.multi_match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multi\_match!}}}}} (but not {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match!}}}}}) can cause
backtracking into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} to select its next success.

\end{description}

\sphinxAtStartPar
Variables from the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat1}]{\sphinxcrossref{\DUrole{hole}{tac2pat1}}}}}}} are statically bound in the body of the branch.
Variables from the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} pattern have values of type \sphinxcode{\sphinxupquote{constr}}.
Variables from the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in the \sphinxcode{\sphinxupquote{context}} construct have values of type
\sphinxcode{\sphinxupquote{Pattern.context}} (defined in \sphinxcode{\sphinxupquote{Pattern.v}}).

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
Note that unlike Ltac1, only lowercase identifiers are valid as Ltac2
bindings.  Ltac2 will report an error if one of the bound variables
starts with an uppercase character.

\sphinxAtStartPar
The semantics of this construction are otherwise the same as the corresponding
one from Ltac1, except that it requires the goal to be focused.

\phantomsection\label{\detokenize{proof-engine/ltac2:ltac2-match-vs-lazymatch-ex}}
\begin{sphinxadmonition}{note}{Example: Ltac2 Comparison of lazy\_match! and match!}

\sphinxAtStartPar
(Equivalent to this {\hyperref[\detokenize{proof-engine/ltac:match-vs-lazymatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac1 example}}}}.)

\sphinxAtStartPar
These lines define a \sphinxcode{\sphinxupquote{msg}} tactic that's used in several examples as a more\sphinxhyphen{}succinct
alternative to \sphinxcode{\sphinxupquote{print (to\_string "...")}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{From} \PYG{n}{Ltac2} \PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Message}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{n}{msg} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{print} \PYG{o}{(}\PYG{n}{of\PYGZus{}string} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
In {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.lazy_match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazy\_match!}}}}}, if {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr}}}}} fails, the {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.lazy_match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazy\_match!}}}}} fails;
it doesn't look for further matches.  In {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match!}}}}}, if {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr}}}}} fails
in a matching branch, it will try to match on subsequent branches.  Note that
\sphinxcode{\sphinxupquote{\DUrole{notation}{\textquotesingle{}{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} below is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{open\_constr:({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{n}{lazy\PYGZus{}match}\PYG{o}{!} \PYG{k}{\PYGZsq{}}\PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \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}{Uncaught} \PYG{n}{Ltac2} \PYG{n}{exception}\PYG{o}{:} \PYG{n}{Tactic\PYGZus{}failure} \PYG{o}{(}\PYG{n}{None}\PYG{o}{)}


\PYG{k}{match}\PYG{o}{!} \PYG{k}{\PYGZsq{}}\PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \PYG{n}{branch} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/ltac2:ltac2-match-vs-multimatch-ex}}
\begin{sphinxadmonition}{note}{Example: Ltac2 Comparison of match! and multi\_match!}

\sphinxAtStartPar
(Equivalent to this {\hyperref[\detokenize{proof-engine/ltac:match-vs-multimatch-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac1 example}}}}.)

\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match!}}}}} tactics are only evaluated once, whereas {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.multi_match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multi\_match!}}}}}
tactics may be evaluated more than once if the following constructs trigger backtracking:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k}{match}\PYG{o}{!} \PYG{k}{\PYGZsq{}}\PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end} \PYG{o}{;}
\PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \PYG{n}{branch} \PYG{n}{A}
    \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}{Uncaught} \PYG{n}{Ltac2} \PYG{n}{exception}\PYG{o}{:} \PYG{n}{Tactic\PYGZus{}failure} \PYG{o}{(}\PYG{n}{None}\PYG{o}{)}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{n}{multi\PYGZus{}match}\PYG{o}{!} \PYG{k}{\PYGZsq{}}\PYG{n}{True} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 1}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch 2}\PYG{l+s+s2}{\PYGZdq{}}
\PYG{k}{end} \PYG{o}{;}
\PYG{n}{msg} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{branch A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{.}
    \PYG{n}{branch} \PYG{l+m+mi}{1}
    \PYG{n}{branch} \PYG{n}{A}
    \PYG{n}{branch} \PYG{l+m+mi}{2}
    \PYG{n}{branch} \PYG{n}{A}
    \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}{Uncaught} \PYG{n}{Ltac2} \PYG{n}{exception}\PYG{o}{:} \PYG{n}{Match\PYGZus{}failure}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/ltac2:ltac2-match-with-holes-ex}}\phantomsection\label{\detokenize{proof-engine/ltac2:ltac2-match-term-context-ex}}
\begin{sphinxadmonition}{note}{Example: Ltac2 Multiple matches for a "context" pattern.}

\sphinxAtStartPar
(Equivalent to this {\hyperref[\detokenize{proof-engine/ltac:match-term-context-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac1 example}}}}.)

\sphinxAtStartPar
Internally "x <> y" is represented as "(\textasciitilde{} (x = y))", which produces the
first match.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Ltac2} \PYG{n}{f2} \PYG{n}{t} \PYG{o}{:=} \PYG{k}{match}\PYG{o}{!} \PYG{n}{t} \PYG{k}{with}
              \PYG{o}{|} \PYG{n}{context} \PYG{o}{[} \PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{o}{?}\PYG{n}{t}\PYG{o}{)} \PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{n}{print} \PYG{o}{(}\PYG{n}{of\PYGZus{}constr} \PYG{n}{t}\PYG{o}{)}\PYG{o}{;} \PYG{n}{fail}
              \PYG{o}{|} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{()}
              \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{f2} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{n}{False}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{(}\PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{n}{False}\PYG{o}{)}\PYG{o}{)}
    \PYG{n}{True}
    \PYG{n}{False}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Match over goals}
\label{\detokenize{proof-engine/ltac2:match-over-goals}}\index{lazy\_match"! goal (tactic)@\spxentry{lazy\_match"! goal}\spxextra{tactic}}\index{match"! goal (tactic)@\spxentry{match"! goal}\spxextra{tactic}}\index{multi\_match"! goal (tactic)@\spxentry{multi\_match"! goal}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:tacn.lazy_match!-goal}}\phantomsection\label{\detokenize{proof-engine/ltac2:coq:tacn.match!-goal}}\phantomsection\label{\detokenize{proof-engine/ltac2:coq:tacn.multi_match!-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_key}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_key}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{reverse}\DUrole{notation-sup}{?}}~goal~with~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-goal_match_list}]{\sphinxcrossref{\DUrole{hole}{goal\_match\_list}}}}~end}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-goal_match_list}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-goal_match_list}]{\sphinxcrossref{\DUrole{hole}{goal\_match\_list}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_rule}]{\sphinxcrossref{\DUrole{hole}{gmatch\_rule}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-gmatch_rule}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_rule}]{\sphinxcrossref{\DUrole{hole}{gmatch\_rule}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_pattern}]{\sphinxcrossref{\DUrole{hole}{gmatch\_pattern}}}} => {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-gmatch_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_pattern}]{\sphinxcrossref{\DUrole{hole}{gmatch\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_hyp_pattern}]{\sphinxcrossref{\DUrole{hole}{gmatch\_hyp\_pattern}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} |\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_pattern}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-gmatch_hyp_pattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_hyp_pattern}]{\sphinxcrossref{\DUrole{hole}{gmatch\_hyp\_pattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} : {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_pattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
Matches over goals, similar to Ltac1 {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}}.
Use this form to match hypotheses and/or goals in the local context.  These patterns have zero or
more subpatterns to match hypotheses followed by a subpattern to match the conclusion.  Except for the
differences noted below, this works the same as the corresponding \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_key}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_key}}}} {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}} construct
(see {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.match!}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match!}}}}}).  Each current goal is processed independently.

\sphinxAtStartPar
Matching is non\sphinxhyphen{}linear: if a
metavariable occurs more than once, each occurrence must match the same
expression.  Within a single term, expressions match if they are syntactically equal or
{\hyperref[\detokenize{language/core/conversion:term-alpha-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{α\sphinxhyphen{}convertible}}}}.  When a metavariable is used across
multiple hypotheses or across a hypothesis and the current goal, the expressions match if
they are {\hyperref[\detokenize{language/core/conversion:term-convertible}]{\sphinxtermref{\DUrole{xref,std,std-term}{convertible}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_pattern}]{\sphinxcrossref{\DUrole{hole}{gmatch\_pattern}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}}}}}}] \leavevmode
\sphinxAtStartPar
Patterns to match with hypotheses.  Each pattern must match a distinct hypothesis in order
for the branch to match.

\sphinxAtStartPar
Hypotheses have the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{:= {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{binder}}$}}}}}\DUrole{notation-sup}{?}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}.  Currently Ltac2 doesn't
allow matching on or capturing the value of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{binder}}$}}}}}}}.  It only supports matching on
the {\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} and the {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}, for example \sphinxcode{\sphinxupquote{n : ?t}}.

\sphinxAtStartPar
If there are multiple {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_hyp_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gmatch\_hyp\_pattern}}}}}s in a branch, there may be multiple ways to match them to hypotheses.
For {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.match!-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match! goal}}}}} and {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.multi_match!-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{multi\_match! goal}}}}}, if the evaluation of the {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr}}}}} fails,
matching will continue with the next hypothesis combination.  When those are exhausted,
the next alternative from any \sphinxcode{\sphinxupquote{context}} construct in the {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_match\_pattern}}}}}s is tried and then,
when the context alternatives are exhausted, the next branch is tried.
{\hyperref[\detokenize{proof-engine/ltac2:ltac2-match-goal-multiple-hyps-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Example}}}}.

\item[{\sphinxcode{\sphinxupquote{reverse}}}] \leavevmode
\sphinxAtStartPar
Hypothesis matching for {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_hyp_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gmatch\_hyp\_pattern}}}}}s normally begins by matching them from left to right,
to hypotheses, last to first.  Specifying \sphinxcode{\sphinxupquote{reverse}} begins matching in the reverse order, from
first to last.  {\hyperref[\detokenize{proof-engine/ltac2:ltac2-match-goal-hyps-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Normal}}}} and {\hyperref[\detokenize{proof-engine/ltac2:ltac2-match-goal-hyps-rev-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{reverse}}}} examples.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{|\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_pattern}}}}}}}}] \leavevmode
\sphinxAtStartPar
A pattern to match with the current goal

\end{description}

\sphinxAtStartPar
Note that unlike Ltac1, only lowercase identifiers are valid as Ltac2
bindings.  Ltac2 will report an error if you try to use a bound variable
that starts with an uppercase character.

\sphinxAtStartPar
Variables from \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-gmatch_hyp_pattern}]{\sphinxcrossref{\DUrole{hole}{gmatch\_hyp\_pattern}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_pattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_match\_pattern}}}}}}} are
bound in the body of the branch. Their types are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{constr}} for pattern variables appearing in a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Pattern.context}} for variables binding a context

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ident}} for variables binding a hypothesis name.

\end{itemize}

\sphinxAtStartPar
The same identifier caveat as in the case of matching over constr applies, and
this feature has the same semantics as in Ltac1.

\end{fulllineitems}\end{savenotes}

\phantomsection\label{\detokenize{proof-engine/ltac2:ltac2-match-goal-hyps-ex}}
\begin{sphinxadmonition}{note}{Example: Ltac2 Matching hypotheses}

\sphinxAtStartPar
(Equivalent to this {\hyperref[\detokenize{proof-engine/ltac:match-goal-hyps-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac1 example}}}}.)

\sphinxAtStartPar
Hypotheses are matched from the last hypothesis (which is by default the newest
hypothesis) to the first until the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} succeeds.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}

\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{B}
      \PYG{n}{H1} \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}{B}

\PYG{k}{match}\PYG{o}{!} \PYG{n}{goal} \PYG{k}{with}
\PYG{o}{|} \PYG{o}{[} \PYG{n}{h} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{k}{let} \PYG{n}{h} \PYG{o}{:=} \PYG{n}{Control}\PYG{o}{.}\PYG{n}{hyp} \PYG{n}{h} \PYG{k}{in} \PYG{n}{print} \PYG{o}{(}\PYG{n}{of\PYGZus{}constr} \PYG{n}{h}\PYG{o}{)}\PYG{o}{;} \PYG{k}{apply} \PYG{o}{\PYGZdl{}}\PYG{n}{h}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{H1}
    \PYG{n}{H0}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/ltac2:ltac2-match-goal-hyps-rev-ex}}
\begin{sphinxadmonition}{note}{Example: Matching hypotheses with reverse}

\sphinxAtStartPar
(Equivalent to this {\hyperref[\detokenize{proof-engine/ltac:match-goal-hyps-rev-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac1 example}}}}.)

\sphinxAtStartPar
Hypotheses are matched from the first hypothesis to the last until the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} succeeds.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}

\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{B}
      \PYG{n}{H1} \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}{B}

\PYG{k}{match}\PYG{o}{!} \PYG{n}{reverse} \PYG{n}{goal} \PYG{k}{with}
\PYG{o}{|} \PYG{o}{[} \PYG{n}{h} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{k}{let} \PYG{n}{h} \PYG{o}{:=} \PYG{n}{Control}\PYG{o}{.}\PYG{n}{hyp} \PYG{n}{h} \PYG{k}{in} \PYG{n}{print} \PYG{o}{(}\PYG{n}{of\PYGZus{}constr} \PYG{n}{h}\PYG{o}{)}\PYG{o}{;} \PYG{k}{apply} \PYG{o}{\PYGZdl{}}\PYG{n}{h}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{A}
    \PYG{n}{B}
    \PYG{n}{H}
    \PYG{n}{H0}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{proof-engine/ltac2:ltac2-match-goal-multiple-hyps-ex}}
\begin{sphinxadmonition}{note}{Example: Multiple ways to match a hypotheses}

\sphinxAtStartPar
(Equivalent to this {\hyperref[\detokenize{proof-engine/ltac:match-goal-multiple-hyps-ex}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac1 example}}}}.)

\sphinxAtStartPar
Every possible match for the hypotheses is evaluated until the right\sphinxhyphen{}hand
side succeeds.  Note that \sphinxcode{\sphinxupquote{h1}} and \sphinxcode{\sphinxupquote{h2}} are never matched to the same hypothesis.
Observe that the number of permutations can grow as the factorial
of the number of hypotheses and hypothesis patterns.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}

\PYG{k}{intros} \PYG{n}{A} \PYG{n}{B} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \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}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}

\PYG{k}{match}\PYG{o}{!} \PYG{n}{goal} \PYG{k}{with}
\PYG{o}{|} \PYG{o}{[} \PYG{n}{h1} \PYG{o}{:} \PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{n}{h2} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{]} \PYG{o}{=\PYGZgt{}}
   \PYG{n}{print} \PYG{o}{(}\PYG{n}{concat} \PYG{o}{(}\PYG{n}{of\PYGZus{}string} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{match }\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}
         \PYG{o}{(}\PYG{n}{concat} \PYG{o}{(}\PYG{n}{of\PYGZus{}constr} \PYG{o}{(}\PYG{n}{Control}\PYG{o}{.}\PYG{n}{hyp} \PYG{n}{h1}\PYG{o}{)}\PYG{o}{)}
         \PYG{o}{(}\PYG{n}{concat} \PYG{o}{(}\PYG{n}{of\PYGZus{}string} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ }\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}
         \PYG{o}{(}\PYG{n}{of\PYGZus{}constr} \PYG{o}{(}\PYG{n}{Control}\PYG{o}{.}\PYG{n}{hyp} \PYG{n}{h2}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{;}
   \PYG{n}{fail}
\PYG{o}{|} \PYG{o}{[} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{]} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{()}
\PYG{k}{end}\PYG{o}{.}
    \PYG{k}{match} \PYG{n}{B} \PYG{n}{H}
    \PYG{k}{match} \PYG{n}{A} \PYG{n}{H}
    \PYG{k}{match} \PYG{n}{H} \PYG{n}{B}
    \PYG{k}{match} \PYG{n}{A} \PYG{n}{B}
    \PYG{k}{match} \PYG{n}{H} \PYG{n}{A}
    \PYG{k}{match} \PYG{n}{B} \PYG{n}{A}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Match on values}
\label{\detokenize{proof-engine/ltac2:match-on-values}}\index{match (Ltac2) (tactic)@\spxentry{match (Ltac2)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:tacn.match-(Ltac2)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{match~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_branches}]{\sphinxcrossref{\DUrole{hole}{ltac2\_branches}}}}}\DUrole{notation-sup}{?}}~end}}}}
\sphinxAtStartPar
Matches a value, akin to the OCaml \sphinxcode{\sphinxupquote{match}} construct.  By itself, it doesn't cause backtracking
as do the \sphinxcode{\sphinxupquote{*match*!}} and \sphinxcode{\sphinxupquote{*match*! goal}} constructs.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_branches}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_branches}]{\sphinxcrossref{\DUrole{hole}{ltac2\_branches}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{|}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat1}]{\sphinxcrossref{\DUrole{hole}{tac2pat1}}}} => {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2pat1}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat1}]{\sphinxcrossref{\DUrole{hole}{tac2pat1}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\DUrole{hole}{tac2pat0}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\DUrole{hole}{tac2pat0}}}} :: {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\DUrole{hole}{tac2pat0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\DUrole{hole}{tac2pat0}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat0}]{\sphinxcrossref{\DUrole{hole}{tac2pat0}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{()}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-atomic_tac2pat}]{\sphinxcrossref{\DUrole{hole}{atomic\_tac2pat}}}}}\DUrole{notation-sup}{?}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-atomic_tac2pat}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-atomic_tac2pat}]{\sphinxcrossref{\DUrole{hole}{atomic\_tac2pat}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat1}]{\sphinxcrossref{\DUrole{hole}{tac2pat1}}}} : {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_type}]{\sphinxcrossref{\DUrole{hole}{ltac2\_type}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat1}]{\sphinxcrossref{\DUrole{hole}{tac2pat1}}}} , \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat1}]{\sphinxcrossref{\DUrole{hole}{tac2pat1}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-tac2pat1}]{\sphinxcrossref{\DUrole{hole}{tac2pat1}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\end{fulllineitems}\end{savenotes}

\index{if\sphinxhyphen{}then\sphinxhyphen{}else (Ltac2) (tactic)@\spxentry{if\sphinxhyphen{}then\sphinxhyphen{}else (Ltac2)}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:tacn.if-then-else-(Ltac2)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{if~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5$_{\text{test}}$}}}}~then~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5$_{\text{then}}$}}}}~else~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5$_{\text{else}}$}}}}}}}}
\sphinxAtStartPar
Equivalent to a {\hyperref[\detokenize{proof-engine/ltac2:coq:tacn.match-(Ltac2)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}} on a boolean value.  If the
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5$_{\text{test}}$}}}}}}} evaluates to true, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5$_{\text{then}}$}}}}}}}
is evaluated.  Otherwise \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr5$_{\text{else}}$}}}}}}} is evaluated.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
For now, deep pattern matching is not implemented.
\end{sphinxadmonition}


\subsubsection{Notations}
\label{\detokenize{proof-engine/ltac2:notations}}\label{\detokenize{proof-engine/ltac2:ltac2-notations}}\index{Ltac2 Notation (command)@\spxentry{Ltac2 Notation}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-Notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~Notation~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}}}~
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac2 Notation}}}}} provides a way to extend the syntax of Ltac2 tactics.  The left\sphinxhyphen{}hand
side (before the \sphinxcode{\sphinxupquote{:=}}) defines the syntax to recognize and gives formal parameter
names for the syntactic values.  \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}} is the level of the notation.
When the notation is used, the values are substituted
into the right\sphinxhyphen{}hand side.  The right\sphinxhyphen{}hand side is typechecked when the notation is used,
not when it is defined.  In the following example, \sphinxcode{\sphinxupquote{x}} is the formal parameter name and
\sphinxcode{\sphinxupquote{constr}} is its {\hyperref[\detokenize{proof-engine/ltac2:syntactic-classes}]{\sphinxcrossref{\DUrole{std,std-ref}{syntactic class}}}}.  \sphinxcode{\sphinxupquote{print}} and \sphinxcode{\sphinxupquote{of\_constr}} are
functions provided by Coq through \sphinxcode{\sphinxupquote{Message.v}}.

\begin{sphinxadmonition}{note}{Example: Printing a \sphinxstyleliteralintitle{\sphinxupquote{term}}}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{From} \PYG{n}{Ltac2} \PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Message}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ex1}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{x}\PYG{o}{(}\PYG{n}{constr}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{print} \PYG{o}{(}\PYG{n}{of\PYGZus{}constr} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{ex1} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{2}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
You can also print terms with a regular Ltac2 definition, but then the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} must be in
the quotation \sphinxcode{\sphinxupquote{constr:( … )}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Ltac2} \PYG{n}{ex2} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{print} \PYG{o}{(}\PYG{n}{of\PYGZus{}constr} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{ex2} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{l+m+mi}{1}\PYG{o}{+}\PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{2}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
There are also metasyntactic classes described {\hyperref[\detokenize{proof-engine/ltac2:syntactic-classes}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}
that combine other items.  For example, \sphinxcode{\sphinxupquote{list1(constr, ",")}}
recognizes a comma\sphinxhyphen{}separated list of one or more {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}s.

\begin{sphinxadmonition}{note}{Example: Parsing a list of \sphinxstyleliteralintitle{\sphinxupquote{term}}s}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Ltac2} \PYG{n}{rec} \PYG{n}{print\PYGZus{}list} \PYG{n}{x} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{a} \PYG{o}{::} \PYG{n}{t} \PYG{o}{=\PYGZgt{}} \PYG{n}{print} \PYG{o}{(}\PYG{n}{of\PYGZus{}constr} \PYG{n}{a}\PYG{o}{)}\PYG{o}{;} \PYG{n}{print\PYGZus{}list} \PYG{n}{t}
\PYG{o}{|} \PYG{n+nb+bp}{[]} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{()}
\PYG{k}{end}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ex2}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{x}\PYG{o}{(}\PYG{n}{list1}\PYG{o}{(}\PYG{n}{constr}\PYG{o}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{,}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{print\PYGZus{}list} \PYG{n}{x}\PYG{o}{.}
\PYG{n}{ex2} \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}{1}
    \PYG{l+m+mi}{2}
    \PYG{l+m+mi}{3}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
An Ltac2 notation adds a parsing rule to the Ltac2 grammar, which is expanded
to the provided body where every token from the notation is let\sphinxhyphen{}bound to the
corresponding generated expression.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Assume we perform:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Ltac2} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{foo}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{c}\PYG{o}{(}\PYG{n}{thunk}\PYG{o}{(}\PYG{n}{constr}\PYG{o}{)}\PYG{o}{)} \PYG{n}{ids}\PYG{o}{(}\PYG{n}{list0}\PYG{o}{(}\PYG{n}{ident}\PYG{o}{)}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{Bar}\PYG{o}{.}\PYG{n}{f} \PYG{n}{c} \PYG{n}{ids}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Then the following expression

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{let y := @X in foo (nat \sphinxhyphen{}> nat) x \$y}}

\sphinxAtStartPar
will expand at parsing time to

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{let y := @X in}}
\sphinxcode{\sphinxupquote{let c := fun () => constr:(nat \sphinxhyphen{}> nat) with ids := {[}@x; y{]} in Bar.f c ids}}

\sphinxAtStartPar
Beware that the order of evaluation of multiple let\sphinxhyphen{}bindings is not specified,
so that you may have to resort to thunking to ensure that side\sphinxhyphen{}effects are
performed at the right time.
\end{sphinxadmonition}

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{using/libraries/writing:coq:attr.deprecated}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{deprecated}}}}} attribute.
\index{Notation levels must range between 0 and 6 (error)@\spxentry{Notation levels must range between 0 and 6}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:exn.Notation-levels-must-range-between-0-and-6}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Notation~levels~must~range~between~0~and~6.}}}}
\sphinxAtStartPar
The level of a notation must be an integer between 0 and 6 inclusive.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\paragraph{Abbreviations}
\label{\detokenize{proof-engine/ltac2:abbreviations}}\index{Ltac2 Notation (abbreviation) (command)@\spxentry{Ltac2 Notation (abbreviation)}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-Notation-(abbreviation)}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~Notation~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}~:=~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}}}
\sphinxAtStartPar
Introduces a special kind of notation, called an abbreviation,
that does not add any parsing rules. It is similar in
spirit to Coq abbreviations (see {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation-(abbreviation)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation (abbreviation)}}}}},
insofar as its main purpose is to give an
absolute name to a piece of pure syntax, which can be transparently referred to
by this name as if it were a proper definition.

\sphinxAtStartPar
The abbreviation can then be manipulated just like a normal Ltac2 definition,
except that it is expanded at internalization time into the given expression.
Furthermore, in order to make this kind of construction useful in practice in
an effectful language such as Ltac2, any syntactic argument to an abbreviation
is thunked on\sphinxhyphen{}the\sphinxhyphen{}fly during its expansion.

\sphinxAtStartPar
For instance, suppose that we define the following.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 Notation foo := fun x => x ().}}}

\sphinxAtStartPar
Then we have the following expansion at internalization time.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{foo 0 ↦ (fun x => x ()) (fun \_ => 0)}}}

\sphinxAtStartPar
Note that abbreviations are not type checked at all, and may result in typing
errors after expansion.

\sphinxAtStartPar
This command supports the {\hyperref[\detokenize{using/libraries/writing:coq:attr.deprecated}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{deprecated}}}}} attribute.

\end{fulllineitems}\end{savenotes}



\paragraph{Defining tactics}
\label{\detokenize{proof-engine/ltac2:defining-tactics}}\label{\detokenize{proof-engine/ltac2:id4}}
\sphinxAtStartPar
Built\sphinxhyphen{}in tactics (those defined in OCaml code in the Coq executable) and Ltac1 tactics,
which are defined in \sphinxcode{\sphinxupquote{.v}} files, must be defined through notations.  (Ltac2 tactics can be
defined with {\hyperref[\detokenize{proof-engine/ltac2:coq:cmd.Ltac2}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac2}}}}}.

\sphinxAtStartPar
Notations for many but not all built\sphinxhyphen{}in tactics are defined in \sphinxcode{\sphinxupquote{Notations.v}}, which is automatically
loaded with Ltac2.  The Ltac2 syntax for these tactics is often identical or very similar to the
tactic syntax described in other chapters of this documentation.  These notations rely on tactic functions
declared in \sphinxcode{\sphinxupquote{Std.v}}.  Functions corresponding to some built\sphinxhyphen{}in tactics may not yet be defined in the
Coq executable or declared in \sphinxcode{\sphinxupquote{Std.v}}.  Adding them may require code changes to Coq or defining
workarounds through Ltac1 (described below).

\sphinxAtStartPar
Two examples of syntax differences:
\begin{itemize}
\item {} 
\sphinxAtStartPar
There is no notation defined that's equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until \DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}}.  There is,
however, already an \sphinxcode{\sphinxupquote{intros\_until}} tactic function defined \sphinxcode{\sphinxupquote{Std.v}}, so it may be possible for a user
to add the necessary notation.

\item {} 
\sphinxAtStartPar
The built\sphinxhyphen{}in \sphinxcode{\sphinxupquote{simpl}} tactic in Ltac1 supports the use of scope keys in delta flags, e.g. \sphinxcode{\sphinxupquote{\DUrole{notation}{simpl {[}"+"\%nat{]}}}}
which is not accepted by Ltac2.  This is because Ltac2 uses a different
definition for {\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-delta_reductions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{delta\_reductions}}}}}; compare it to {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_delta_reductions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_delta\_reductions}}}}}.  This also affects
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{compute}}}}}.

\end{itemize}

\sphinxAtStartPar
Ltac1 tactics are not automatically available in Ltac2.  (Note that some of the tactics described
in the documentation are defined with Ltac1.)
You can make them accessible in Ltac2 with commands similar to the following:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{From} \PYG{n}{Coq} \PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Lia}\PYG{o}{.}
\PYG{k+kn}{Local} \PYG{n}{Ltac2} \PYG{n}{lia\PYGZus{}ltac1} \PYG{n+nb+bp}{()} \PYG{o}{:=} \PYG{n}{ltac1}\PYG{o}{:}\PYG{o}{(}\PYG{n}{lia}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{lia}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{lia\PYGZus{}ltac1} \PYG{n+nb+bp}{()}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
A similar approach can be used to access missing built\sphinxhyphen{}in tactics.  See {\hyperref[\detokenize{proof-engine/ltac2:simple-api}]{\sphinxcrossref{\DUrole{std,std-ref}{Simple API}}}} for an
example that passes two parameters to a missing build\sphinxhyphen{}in tactic.


\paragraph{Syntactic classes}
\label{\detokenize{proof-engine/ltac2:syntactic-classes}}\label{\detokenize{proof-engine/ltac2:id5}}
\sphinxAtStartPar
The simplest syntactic classes in Ltac2 notations represent individual nonterminals
from the Coq grammar.  Only a few selected nonterminals are available as syntactic classes.
In addition, there are metasyntactic operations for describing
more complex syntax, such as making an item optional or representing a list of items.
When parsing, each syntactic class expression returns a value that's bound to a name in the
notation definition.

\sphinxAtStartPar
Syntactic classes are described with a form of S\sphinxhyphen{}expression:
\begin{quote}
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}} ( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\end{quote}

\sphinxAtStartPar
Metasyntactic operations that can be applied to other syntactic classes are:
\begin{quote}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{opt({\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}})}}}}] \leavevmode
\sphinxAtStartPar
Parses an optional {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_scope}}}}}.  The associated value is either \sphinxcode{\sphinxupquote{\DUrole{notation}{None}}} or
enclosed in \sphinxcode{\sphinxupquote{\DUrole{notation}{Some}}}

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{list1({\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{, {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}})}}}}] \leavevmode
\sphinxAtStartPar
Parses a list of one or more {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_scope}}}}}s.  If {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} is specified,
items must be separated by {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{list0({\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{, {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}})}}}}] \leavevmode
\sphinxAtStartPar
Parses a list of zero or more {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_scope}}}}}s.  If {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} is specified,
items must be separated by {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}.  For zero items, the associated value
is an empty list.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{seq(\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}})}}}}] \leavevmode
\sphinxAtStartPar
Parses the {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_scope}}}}}s in order.  The associated value is a tuple,
omitting {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_scope}}}}}s that are {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}s.
\sphinxcode{\sphinxupquote{self}} and \sphinxcode{\sphinxupquote{next}} are not permitted within \sphinxcode{\sphinxupquote{seq}}.

\end{description}
\end{quote}

\sphinxAtStartPar
The following classes represent nonterminals with some special handling.  The
table further down lists the classes that that are handled plainly.
\begin{quote}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{constr \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Parses a {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.  If specified, the {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_key}}}}}s are used to interpret
the term (as described in  {\hyperref[\detokenize{user-extensions/syntax-extensions:localinterpretationrulesfornotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Local interpretation rules for notations}}}}).  The last
{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope\_key}}}}} is the top of the scope stack that's applied to the {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{open\_constr \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope_key}]{\sphinxcrossref{\DUrole{hole}{scope\_key}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Parses an open {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. Like \sphinxcode{\sphinxupquote{\DUrole{notation}{constr}}} above, this class
accepts a list of notation scopes with the same effects.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{ident}}}}] \leavevmode
\sphinxAtStartPar
Parses {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{\${\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.  The first form returns \sphinxcode{\sphinxupquote{\DUrole{notation}{ident:({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}},
while the latter form returns the variable \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}] \leavevmode
\sphinxAtStartPar
Accepts the specified string that is not a keyword, returning a value of \sphinxcode{\sphinxupquote{()}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{keyword({\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}})}}}}] \leavevmode
\sphinxAtStartPar
Accepts the specified string that is a keyword, returning a value of \sphinxcode{\sphinxupquote{()}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{terminal({\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}})}}}}] \leavevmode
\sphinxAtStartPar
Accepts the specified string whether it's a keyword or not, returning a value of \sphinxcode{\sphinxupquote{()}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{tactic \DUrole{repeat-wrapper}{\DUrole{repeat}{({\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}})}\DUrole{notation-sup}{?}}}}}}] \leavevmode
\sphinxAtStartPar
Parses an {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr}}}}}.  If {\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} is specified, the construct
parses a \sphinxcode{\sphinxupquote{\DUrole{notation}{ltac2\_expr{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}}, for example \sphinxcode{\sphinxupquote{tactic(5)}} parses {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr5}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr5}}}}}.
\sphinxcode{\sphinxupquote{tactic(6)}} parses {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_expr}}}}}.
{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} must be in the range \sphinxcode{\sphinxupquote{0 .. 6}}.

\sphinxAtStartPar
You can also use \sphinxcode{\sphinxupquote{tactic}} to accept an {\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} or a {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}, but there's
no syntactic class that accepts \sphinxstyleemphasis{only} an {\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} or a {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}.

\end{description}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{self}}}}] \leavevmode
\sphinxAtStartPar
parses an Ltac2 expression at the current level and returns it as is.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{next}}}}] \leavevmode
\sphinxAtStartPar
parses an Ltac2 expression at the next level and returns it as is.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{thunk({\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}})}}}}] \leavevmode
\sphinxAtStartPar
Used for semantic effect only, parses the same as {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_scope}}}}}.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{e}}} is the parsed expression for {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_scope}}}}}, \sphinxcode{\sphinxupquote{thunk}}
returns \sphinxcode{\sphinxupquote{\DUrole{notation}{fun () => e}}}.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{pattern}}}}] \leavevmode
\sphinxAtStartPar
parses a {\hyperref[\detokenize{proof-engine/ltac:grammar-token-cpattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cpattern}}}}}

\end{description}
\end{quote}

\sphinxAtStartPar
A few syntactic classes contain antiquotation features. For the sake of uniformity, all
antiquotations are introduced by the syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{\${\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}}.

\sphinxAtStartPar
A few other specific syntactic classes exist to handle Ltac1\sphinxhyphen{}like syntax, but their use is
discouraged and they are thus not documented.

\sphinxAtStartPar
For now there is no way to declare new syntactic classes from the Ltac2 side, but this is
planned.

\sphinxAtStartPar
Other nonterminals that have syntactic classes are listed here.
\begin{quote}


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
Syntactic class name
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Nonterminal
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Similar non\sphinxhyphen{}Ltac2 syntax
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{intropatterns}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_intropatterns}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_intropatterns}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern_list}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intropattern\_list}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{intropattern}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_simple\_intropattern}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple\_intropattern}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{ident}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident\_or\_anti}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{destruction\_arg}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_destruction_arg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_destruction\_arg}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{destruction\_arg}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{with\_bindings}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-q_with_bindings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{q\_with\_bindings}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{bindings}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_bindings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_bindings}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bindings}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{reductions}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_reductions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_reductions}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-reductions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reductions}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{reference}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-refglobal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refglobal}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-reference}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reference}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{clause}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_clause}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_clause}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occurrences}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{occurrences}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-q_occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{q\_occurrences}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}\DUrole{notation-sup}{?}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction\_clause}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_induction_clause}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_induction\_clause}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{induction\_clause}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{conversion}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_conversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_conversion}}}}}
&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{rewriting}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_oriented_rewriter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_oriented\_rewriter}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-oriented_rewriter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{oriented\_rewriter}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{dispatch}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_for_each_goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_for\_each\_goal}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac:grammar-token-for_each_goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{for\_each\_goal}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{hintdb}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-hintdb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hintdb}}}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/automatic-tactics/auto:grammar-token-hintbases}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hintbases}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{move\_location}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-move_location}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move\_location}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{where}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{pose}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-pose}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{bindings\_with\_parameters}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{assert}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-assertion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assertion}}}}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{( {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{constr\_matching}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_match_list}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac2\_match\_list}}}}}
&
\sphinxAtStartPar
See {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match}}}}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{goal\_matching}}}
&
\sphinxAtStartPar
{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-goal_match_list}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{goal\_match\_list}}}}}
&
\sphinxAtStartPar
See {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\end{quote}

\sphinxAtStartPar
Here is the syntax for the \sphinxcode{\sphinxupquote{\DUrole{notation}{q\_*}}} nonterminals:
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_intropatterns}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_intropatterns}]{\sphinxcrossref{\DUrole{hole}{ltac2\_intropatterns}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-nonsimple_intropattern}]{\sphinxcrossref{\DUrole{hole}{nonsimple\_intropattern}}}}}\DUrole{notation-sup}{*}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-nonsimple_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-nonsimple_intropattern}]{\sphinxcrossref{\DUrole{hole}{nonsimple\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{*}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{**}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_simple\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_simple\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_naming\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\_}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_or_and_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_or\_and\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_equality_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_equality\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_or_and_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_or_and_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_or\_and\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[} \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_intropatterns}]{\sphinxcrossref{\DUrole{hole}{ltac2\_intropatterns}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{|}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{()}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_simple\_intropattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( \DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_simple\_intropattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\&}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_equality_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_equality_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_equality\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\sphinxhyphen{}>}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{<\sphinxhyphen{}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{[}= {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_intropatterns}]{\sphinxcrossref{\DUrole{hole}{ltac2\_intropatterns}}}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_naming_intropattern}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_naming\_intropattern}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{? {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{?\$ {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{?}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\$ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_destruction_arg}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_destruction_arg}]{\sphinxcrossref{\DUrole{hole}{ltac2\_destruction\_arg}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_constr_with_bindings}]{\sphinxcrossref{\DUrole{hole}{ltac2\_constr\_with\_bindings}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_constr_with_bindings}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_constr_with_bindings}]{\sphinxcrossref{\DUrole{hole}{ltac2\_constr\_with\_bindings}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_bindings}]{\sphinxcrossref{\DUrole{hole}{ltac2\_bindings}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-q_with_bindings}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-q_with_bindings}]{\sphinxcrossref{\DUrole{hole}{q\_with\_bindings}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_bindings}]{\sphinxcrossref{\DUrole{hole}{ltac2\_bindings}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_bindings}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_bindings}]{\sphinxcrossref{\DUrole{hole}{ltac2\_bindings}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_binding}]{\sphinxcrossref{\DUrole{hole}{ltac2\_simple\_binding}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_binding}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_binding}]{\sphinxcrossref{\DUrole{hole}{ltac2\_simple\_binding}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-qhyp}]{\sphinxcrossref{\DUrole{hole}{qhyp}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-qhyp}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-qhyp}]{\sphinxcrossref{\DUrole{hole}{qhyp}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\$ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-lident}]{\sphinxcrossref{\DUrole{hole}{lident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_reductions}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_reductions}]{\sphinxcrossref{\DUrole{hole}{ltac2\_reductions}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_red_flag}]{\sphinxcrossref{\DUrole{hole}{ltac2\_red\_flag}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_delta_reductions}]{\sphinxcrossref{\DUrole{hole}{ltac2\_delta\_reductions}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_red_flag}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_red_flag}]{\sphinxcrossref{\DUrole{hole}{ltac2\_red\_flag}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{beta}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{iota}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{match}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{fix}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{cofix}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{zeta}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{delta \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_delta_reductions}]{\sphinxcrossref{\DUrole{hole}{ltac2\_delta\_reductions}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_delta_reductions}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_delta_reductions}]{\sphinxcrossref{\DUrole{hole}{ltac2\_delta\_reductions}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} {[} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-refglobal}]{\sphinxcrossref{\DUrole{hole}{refglobal}}}}}\DUrole{notation-sup}{+}} {]}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-refglobal}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-refglobal}]{\sphinxcrossref{\DUrole{hole}{refglobal}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\& {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\$ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_clause}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_clause}]{\sphinxcrossref{\DUrole{hole}{ltac2\_clause}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{in {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_in_clause}]{\sphinxcrossref{\DUrole{hole}{ltac2\_in\_clause}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{at {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs_nums}]{\sphinxcrossref{\DUrole{hole}{ltac2\_occs\_nums}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_in_clause}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_in_clause}]{\sphinxcrossref{\DUrole{hole}{ltac2\_in\_clause}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{* \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs}]{\sphinxcrossref{\DUrole{hole}{ltac2\_occs}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{* |\sphinxhyphen{} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_concl_occ}]{\sphinxcrossref{\DUrole{hole}{ltac2\_concl\_occ}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_hypident_occ}]{\sphinxcrossref{\DUrole{hole}{ltac2\_hypident\_occ}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}} \DUrole{repeat-wrapper}{\DUrole{repeat}{|\sphinxhyphen{} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_concl_occ}]{\sphinxcrossref{\DUrole{hole}{ltac2\_concl\_occ}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-q_occurrences}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-q_occurrences}]{\sphinxcrossref{\DUrole{hole}{q\_occurrences}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs}]{\sphinxcrossref{\DUrole{hole}{ltac2\_occs}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs}]{\sphinxcrossref{\DUrole{hole}{ltac2\_occs}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{at {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs_nums}]{\sphinxcrossref{\DUrole{hole}{ltac2\_occs\_nums}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs_nums}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs_nums}]{\sphinxcrossref{\DUrole{hole}{ltac2\_occs\_nums}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\sphinxhyphen{}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{\$ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_concl_occ}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_concl_occ}]{\sphinxcrossref{\DUrole{hole}{ltac2\_concl\_occ}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{* \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs}]{\sphinxcrossref{\DUrole{hole}{ltac2\_occs}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_hypident_occ}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_hypident_occ}]{\sphinxcrossref{\DUrole{hole}{ltac2\_hypident\_occ}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_hypident}]{\sphinxcrossref{\DUrole{hole}{ltac2\_hypident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_occs}]{\sphinxcrossref{\DUrole{hole}{ltac2\_occs}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_hypident}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_hypident}]{\sphinxcrossref{\DUrole{hole}{ltac2\_hypident}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( type of {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( value of {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_induction_clause}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_induction_clause}]{\sphinxcrossref{\DUrole{hole}{ltac2\_induction\_clause}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_destruction_arg}]{\sphinxcrossref{\DUrole{hole}{ltac2\_destruction\_arg}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_or_and_ipat}]{\sphinxcrossref{\DUrole{hole}{ltac2\_as\_or\_and\_ipat}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_eqn_ipat}]{\sphinxcrossref{\DUrole{hole}{ltac2\_eqn\_ipat}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_clause}]{\sphinxcrossref{\DUrole{hole}{ltac2\_clause}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_or_and_ipat}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_or_and_ipat}]{\sphinxcrossref{\DUrole{hole}{ltac2\_as\_or\_and\_ipat}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{as {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_or_and_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_or\_and\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_eqn_ipat}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_eqn_ipat}]{\sphinxcrossref{\DUrole{hole}{ltac2\_eqn\_ipat}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{eqn : {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_naming_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_naming\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_conversion}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_conversion}]{\sphinxcrossref{\DUrole{hole}{ltac2\_conversion}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} with {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_oriented_rewriter}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_oriented_rewriter}]{\sphinxcrossref{\DUrole{hole}{ltac2\_oriented\_rewriter}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{\sphinxhyphen{}>}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{<\sphinxhyphen{}}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_rewriter}]{\sphinxcrossref{\DUrole{hole}{ltac2\_rewriter}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_rewriter}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_rewriter}]{\sphinxcrossref{\DUrole{hole}{ltac2\_rewriter}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{?}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{!}}}\DUrole{notation-sup}{?}} {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_constr_with_bindings}]{\sphinxcrossref{\DUrole{hole}{ltac2\_constr\_with\_bindings}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_for_each_goal}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_for_each_goal}]{\sphinxcrossref{\DUrole{hole}{ltac2\_for\_each\_goal}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_goal_tactics}]{\sphinxcrossref{\DUrole{hole}{ltac2\_goal\_tactics}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_goal_tactics}]{\sphinxcrossref{\DUrole{hole}{ltac2\_goal\_tactics}}}} |}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}\DUrole{notation-sup}{?}} .. \DUrole{repeat-wrapper}{\DUrole{repeat}{| {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_goal_tactics}]{\sphinxcrossref{\DUrole{hole}{ltac2\_goal\_tactics}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_goal_tactics}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_goal_tactics}]{\sphinxcrossref{\DUrole{hole}{ltac2\_goal\_tactics}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{|}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-hintdb}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-hintdb}]{\sphinxcrossref{\DUrole{hole}{hintdb}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{*}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}}}\DUrole{notation-sup}{+}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-move_location}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-move_location}]{\sphinxcrossref{\DUrole{hole}{move\_location}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{at top}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{at bottom}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{after {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{before {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-pose}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-pose}]{\sphinxcrossref{\DUrole{hole}{pose}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_name}]{\sphinxcrossref{\DUrole{hole}{ltac2\_as\_name}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_name}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_name}]{\sphinxcrossref{\DUrole{hole}{ltac2\_as\_name}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{as {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-assertion}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-assertion}]{\sphinxcrossref{\DUrole{hole}{assertion}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}} := {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ident_or_anti}]{\sphinxcrossref{\DUrole{hole}{ident\_or\_anti}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} ) \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_by_tactic}]{\sphinxcrossref{\DUrole{hole}{ltac2\_by\_tactic}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_ipat}]{\sphinxcrossref{\DUrole{hole}{ltac2\_as\_ipat}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_by_tactic}]{\sphinxcrossref{\DUrole{hole}{ltac2\_by\_tactic}}}}}\DUrole{notation-sup}{?}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_ipat}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_as_ipat}]{\sphinxcrossref{\DUrole{hole}{ltac2\_as\_ipat}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{as {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{ltac2\_simple\_intropattern}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac2_by_tactic}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_by_tactic}]{\sphinxcrossref{\DUrole{hole}{ltac2\_by\_tactic}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{by {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}

\subsubsection{Evaluation}
\label{\detokenize{proof-engine/ltac2:evaluation}}
\sphinxAtStartPar
Ltac2 features a toplevel loop that can be used to evaluate expressions.
\index{Ltac2 Eval (command)@\spxentry{Ltac2 Eval}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-Eval}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~Eval~{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}}}}}}
\sphinxAtStartPar
This command evaluates the term in the current proof if there is one, or in the
global environment otherwise, and displays the resulting value to the user
together with its type. This command is pure in the sense that it does not
modify the state of the proof, and in particular all side\sphinxhyphen{}effects are discarded.

\end{fulllineitems}\end{savenotes}



\subsubsection{Debug}
\label{\detokenize{proof-engine/ltac2:debug}}\index{Ltac2 Backtrace (flag)@\spxentry{Ltac2 Backtrace}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:flag.Ltac2-Backtrace}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~Backtrace}}}}
\sphinxAtStartPar
When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is set, toplevel failures will be printed with a backtrace.

\end{fulllineitems}\end{savenotes}



\subsubsection{Compatibility layer with Ltac1}
\label{\detokenize{proof-engine/ltac2:compatibility-layer-with-ltac1}}

\paragraph{Ltac1 from Ltac2}
\label{\detokenize{proof-engine/ltac2:ltac1-from-ltac2}}

\subparagraph{Simple API}
\label{\detokenize{proof-engine/ltac2:simple-api}}\label{\detokenize{proof-engine/ltac2:id6}}
\sphinxAtStartPar
One can call Ltac1 code from Ltac2 by using the \sphinxcode{\sphinxupquote{\DUrole{notation}{ltac1:({\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac1_expr_in_env}]{\sphinxcrossref{\DUrole{hole}{ltac1\_expr\_in\_env}}}})}}} quotation.
See {\hyperref[\detokenize{proof-engine/ltac2:ltac2-built-in-quotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Built\sphinxhyphen{}in quotations}}}}.  It parses
a Ltac1 expression, and semantics of this quotation is the evaluation of the
corresponding code for its side effects. In particular, it cannot return values,
and the quotation has type \sphinxcode{\sphinxupquote{\DUrole{notation}{unit}}}.

\sphinxAtStartPar
Ltac1 \sphinxstylestrong{cannot} implicitly access variables from the Ltac2 scope, but this can
be done with an explicit annotation on the \sphinxcode{\sphinxupquote{\DUrole{notation}{ltac1:(\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}} |\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}})}}}
quotation.  See {\hyperref[\detokenize{proof-engine/ltac2:ltac2-built-in-quotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Built\sphinxhyphen{}in quotations}}}}.  For example:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Local} \PYG{n}{Ltac2} \PYG{n}{replace\PYGZus{}with} \PYG{o}{(}\PYG{n}{lhs}\PYG{o}{:} \PYG{n}{constr}\PYG{o}{)} \PYG{o}{(}\PYG{n}{rhs}\PYG{o}{:} \PYG{n}{constr}\PYG{o}{)} \PYG{o}{:=}
  \PYG{n}{ltac1}\PYG{o}{:}\PYG{o}{(}\PYG{n}{lhs} \PYG{n}{rhs} \PYG{o}{|}\PYG{o}{\PYGZhy{}} \PYG{k}{replace} \PYG{n}{lhs} \PYG{k}{with} \PYG{n}{rhs}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Ltac1}\PYG{o}{.}\PYG{n}{of\PYGZus{}constr} \PYG{n}{lhs}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Ltac1}\PYG{o}{.}\PYG{n}{of\PYGZus{}constr} \PYG{n}{rhs}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{Ltac2} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{replace}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{lhs}\PYG{o}{(}\PYG{n}{constr}\PYG{o}{)} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{with}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{rhs}\PYG{o}{(}\PYG{n}{constr}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{replace\PYGZus{}with} \PYG{n}{lhs} \PYG{n}{rhs}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
The return type of this expression is a function of the same arity as the number
of identifiers, with arguments of type \sphinxcode{\sphinxupquote{Ltac2.Ltac1.t}} (see below). This syntax
will bind the variables in the quoted Ltac1 code as if they had been bound from
Ltac1 itself. Similarly, the arguments applied to the quotation will be passed
at runtime to the Ltac1 code.


\subparagraph{Low\sphinxhyphen{}level API}
\label{\detokenize{proof-engine/ltac2:low-level-api}}\label{\detokenize{proof-engine/ltac2:id7}}
\sphinxAtStartPar
There exists a lower\sphinxhyphen{}level FFI into Ltac1 that is not recommended for daily use,
which is available in the \sphinxcode{\sphinxupquote{Ltac2.Ltac1}} module. This API allows to directly
manipulate dynamically\sphinxhyphen{}typed Ltac1 values, either through the function calls,
or using the \sphinxcode{\sphinxupquote{ltac1val}} quotation. The latter parses the same as \sphinxcode{\sphinxupquote{ltac1}}, but
has type \sphinxcode{\sphinxupquote{Ltac2.Ltac1.t}} instead of \sphinxcode{\sphinxupquote{unit}}, and dynamically behaves as an Ltac1
thunk, i.e. \sphinxcode{\sphinxupquote{ltac1val:(foo)}} corresponds to the tactic closure that Ltac1
would generate from \sphinxcode{\sphinxupquote{idtac; foo}}.

\sphinxAtStartPar
Due to intricate dynamic semantics, understanding when Ltac1 value quotations
focus is very hard. This is why some functions return a continuation\sphinxhyphen{}passing
style value, as it can dispatch dynamically between focused and unfocused
behaviour.

\sphinxAtStartPar
The same mechanism for explicit binding of variables as described in the
previous section applies.


\paragraph{Ltac2 from Ltac1}
\label{\detokenize{proof-engine/ltac2:ltac2-from-ltac1}}
\sphinxAtStartPar
Same as above by switching Ltac1 by Ltac2 and using the \sphinxcode{\sphinxupquote{ltac2}} quotation
instead.
\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{proof-engine/ltac2:grammar-token-ltac_expr}}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac_expr}]{\sphinxcrossref{\DUrole{hole}{ltac\_expr}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{+=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ltac2 : ( {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{ltac2 : ( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} |\sphinxhyphen{} {\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_expr}]{\sphinxcrossref{\DUrole{hole}{ltac2\_expr}}}} )}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The typing rules are dual, that is, the optional identifiers are bound
with type \sphinxcode{\sphinxupquote{Ltac2.Ltac1.t}} in the Ltac2 expression, which is expected to have
type unit. The value returned by this quotation is an Ltac1 function with the
same arity as the number of bound variables.

\sphinxAtStartPar
Note that when no variables are bound, the inner tactic expression is evaluated
eagerly, if one wants to use it as an argument to a Ltac1 function, one has to
resort to the good old \sphinxcode{\sphinxupquote{\DUrole{notation}{idtac; ltac2:(foo)}}} trick. For instance, the code
below will fail immediately and won't print anything.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{From} \PYG{n}{Ltac2} \PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Ltac2}\PYG{o}{.}
\PYG{k+kn}{Set} \PYG{n}{Default} \PYG{k+kn}{Proof} \PYG{n}{Mode} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Classic}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{mytac} \PYG{n}{tac} \PYG{o}{:=} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{I am being evaluated}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{;} \PYG{n}{tac}\PYG{o}{.}
    \PYG{n}{mytac} \PYG{k}{is} \PYG{n}{defined}


\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{c}{(*}\PYG{c}{ Doesn\PYGZsq{}t print anything }\PYG{c}{*)}
\PYG{n}{Fail} \PYG{n}{mytac} \PYG{n}{ltac2}\PYG{o}{:}\PYG{o}{(}\PYG{n}{fail}\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}{Uncaught} \PYG{n}{Ltac2} \PYG{n}{exception}\PYG{o}{:} \PYG{n}{Tactic\PYGZus{}failure} \PYG{o}{(}\PYG{n}{None}\PYG{o}{)}

\PYG{c}{(*}\PYG{c}{ Prints and fails }\PYG{c}{*)}
\PYG{n}{Fail} \PYG{n}{mytac} \PYG{n}{ltac}\PYG{o}{:}\PYG{o}{(}\PYG{k+kr}{idtac}\PYG{o}{;} \PYG{n}{ltac2}\PYG{o}{:}\PYG{o}{(}\PYG{n}{fail}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{I} \PYG{n}{am} \PYG{n}{being} \PYG{n}{evaluated}
    \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}{Uncaught} \PYG{n}{Ltac2} \PYG{n}{exception}\PYG{o}{:} \PYG{n}{Tactic\PYGZus{}failure} \PYG{o}{(}\PYG{n}{None}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
In any case, the value returned by the fully applied quotation is an
unspecified dummy Ltac1 closure and should not be further used.


\paragraph{Switching between Ltac languages}
\label{\detokenize{proof-engine/ltac2:switching-between-ltac-languages}}
\sphinxAtStartPar
We recommend using the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Default-Proof-Mode}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Default Proof Mode}}}}} option to switch between tactic
languages with a proof\sphinxhyphen{}based granularity. This allows to incrementally port
the proof scripts.


\subsubsection{Transition from Ltac1}
\label{\detokenize{proof-engine/ltac2:transition-from-ltac1}}
\sphinxAtStartPar
Owing to the use of a lot of notations, the transition should not be too
difficult. In particular, it should be possible to do it incrementally. That
said, we do \sphinxstyleemphasis{not} guarantee it will be a blissful walk either.
Hopefully, owing to the fact Ltac2 is typed, the interactive dialogue with Coq
will help you.

\sphinxAtStartPar
We list the major changes and the transition strategies hereafter.


\paragraph{Syntax changes}
\label{\detokenize{proof-engine/ltac2:syntax-changes}}
\sphinxAtStartPar
Due to conflicts, a few syntactic rules have changed.
\begin{itemize}
\item {} 
\sphinxAtStartPar
The dispatch tactical \sphinxcode{\sphinxupquote{\DUrole{notation}{tac; {[}foo|bar{]}}}} is now written \sphinxcode{\sphinxupquote{\DUrole{notation}{tac > {[}foo|bar{]}}}}.

\item {} 
\sphinxAtStartPar
Levels of a few operators have been revised. Some tacticals now parse as if
they were normal functions. Parentheses are now required around complex
arguments, such as abstractions. The tacticals affected are:
\sphinxcode{\sphinxupquote{\DUrole{notation}{try}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{repeat}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{do}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{once}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{progress}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{time}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{abstract}}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{idtac}}} is no more. Either use \sphinxcode{\sphinxupquote{\DUrole{notation}{()}}} if you expect nothing to happen,
\sphinxcode{\sphinxupquote{\DUrole{notation}{(fun () => ())}}} if you want a thunk (see next section), or use printing
primitives from the \sphinxcode{\sphinxupquote{\DUrole{notation}{Message}}} module if you want to display something.

\end{itemize}


\paragraph{Tactic delay}
\label{\detokenize{proof-engine/ltac2:tactic-delay}}
\sphinxAtStartPar
Tactics are not magically delayed anymore, neither as functions nor as
arguments. It is your responsibility to thunk them beforehand and apply them
at the call site.

\sphinxAtStartPar
A typical example of a delayed function:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac foo := blah.}}}

\sphinxAtStartPar
becomes

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 foo () := blah.}}}

\sphinxAtStartPar
All subsequent calls to \sphinxcode{\sphinxupquote{foo}} must be applied to perform the same effect as
before.

\sphinxAtStartPar
Likewise, for arguments:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac bar tac := tac; tac; tac.}}}

\sphinxAtStartPar
becomes

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 bar tac := tac (); tac (); tac ().}}}

\sphinxAtStartPar
We recommend the use of syntactic notations to ease the transition. For
instance, the first example can alternatively be written as:

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 foo0 () := blah.}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 Notation foo := foo0 ().}}}

\sphinxAtStartPar
This allows to keep the subsequent calls to the tactic as\sphinxhyphen{}is, as the
expression \sphinxcode{\sphinxupquote{foo}} will be implicitly expanded everywhere into \sphinxcode{\sphinxupquote{foo0 ()}}. Such
a trick also works for arguments, as arguments of syntactic notations are
implicitly thunked. The second example could thus be written as follows.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 bar0 tac := tac (); tac (); tac ().}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac2 Notation bar := bar0.}}}


\paragraph{Variable binding}
\label{\detokenize{proof-engine/ltac2:variable-binding}}
\sphinxAtStartPar
Ltac1 relies on complex dynamic trickery to be able to tell apart bound
variables from terms, hypotheses, etc. There is no such thing in Ltac2,
as variables are recognized statically and other constructions do not live in
the same syntactic world. Due to the abuse of quotations, it can sometimes be
complicated to know what a mere identifier represents in a tactic expression. We
recommend tracking the context and letting the compiler print typing errors to
understand what is going on.

\sphinxAtStartPar
We list below the typical changes one has to perform depending on the static
errors produced by the typechecker.


\subparagraph{In Ltac expressions}
\label{\detokenize{proof-engine/ltac2:in-ltac-expressions}}\index{Unbound {[}value\textbar{}constructor{]} X (error)@\spxentry{Unbound {[}value\textbar{}constructor{]} X}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:exn.Unbound-_value|constructor_-X}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unbound~\DUrole{alternative}{\DUrole{alternative-block}{value}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{constructor}}~X}}}}~\begin{itemize}
\item {} 
\sphinxAtStartPar
if \sphinxcode{\sphinxupquote{X}} is meant to be a term from the current static environment, replace
the problematic use by \sphinxcode{\sphinxupquote{'X}}.

\item {} 
\sphinxAtStartPar
if \sphinxcode{\sphinxupquote{X}} is meant to be a hypothesis from the local context, replace the
problematic use by \sphinxcode{\sphinxupquote{\&X}}.

\end{itemize}

\end{fulllineitems}\end{savenotes}



\subparagraph{In quotations}
\label{\detokenize{proof-engine/ltac2:in-quotations}}\index{The reference X was not found in the current environment (error)@\spxentry{The reference X was not found in the current environment}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac2:coq:exn.The-reference-X-was-not-found-in-the-current-environment}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~reference~X~was~not~found~in~the~current~environment}}}}~\begin{itemize}
\item {} 
\sphinxAtStartPar
if \sphinxcode{\sphinxupquote{X}} is meant to be a tactic expression bound by a Ltac2 let or function,
replace the problematic use by \sphinxcode{\sphinxupquote{\$X}}.

\item {} 
\sphinxAtStartPar
if \sphinxcode{\sphinxupquote{X}} is meant to be a hypothesis from the local context, replace the
problematic use by \sphinxcode{\sphinxupquote{\&X}}.

\end{itemize}

\end{fulllineitems}\end{savenotes}



\paragraph{Exception catching}
\label{\detokenize{proof-engine/ltac2:exception-catching}}
\sphinxAtStartPar
Ltac2 features a proper exception\sphinxhyphen{}catching mechanism. For this reason, the
Ltac1 mechanism relying on \sphinxcode{\sphinxupquote{fail}} taking integers, and tacticals decreasing it,
has been removed. Now exceptions are preserved by all tacticals, and it is
your duty to catch them and re\sphinxhyphen{}raise them as needed.


\chapter{Using Coq}
\label{\detokenize{index:using-coq}}

\section{Libraries and plugins}
\label{\detokenize{using/libraries/index:libraries-and-plugins}}\label{\detokenize{using/libraries/index:libraries}}\label{\detokenize{using/libraries/index::doc}}
\sphinxAtStartPar
Coq is distributed with a standard library and a set of internal
plugins (most of which provide tactics that have already been
presented in {\hyperref[\detokenize{proofs/writing-proofs/index:writing-proofs}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic proof writing}}}}).  This chapter presents this
standard library and some of these internal plugins which provide
features that are not tactics.

\sphinxAtStartPar
In addition, Coq has a rich ecosystem of external libraries and
plugins.  These libraries and plugins can be browsed online through
the \sphinxhref{https://coq.inria.fr/opam/www/}{Coq Package Index}%
\begin{footnote}[55]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.inria.fr/opam/www/}
%
\end{footnote} and
installed with the \sphinxhref{https://coq.inria.fr/opam-using.html}{opam package manager}%
\begin{footnote}[56]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.inria.fr/opam-using.html}
%
\end{footnote}.


\subsection{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@\spxentry{Theories}}\ignorespaces 
\sphinxAtStartPar
The Coq library has two parts:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The \DUrole{term-defn}{\phantomsection\label{\detokenize{language/coq-library:term-prelude}}prelude}: definitions and theorems for
the most commonly used elementary logical notions and
data types. Coq normally loads these files automatically when it starts.

\item {} 
\sphinxAtStartPar
The \DUrole{term-defn}{\phantomsection\label{\detokenize{language/coq-library:term-standard-library}}standard library}: general\sphinxhyphen{}purpose libraries with
definitions and theorems for sets, lists, sorting,
arithmetic, etc. To use these files, users must load them explicitly
with the \sphinxcode{\sphinxupquote{Require}} command (see {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}})

\end{itemize}

\sphinxAtStartPar
There are also many libraries provided by Coq users' community.
These libraries and developments are available
for download at \sphinxurl{http://coq.inria.fr} (see {\hyperref[\detokenize{language/coq-library:userscontributions}]{\sphinxcrossref{\DUrole{std,std-ref}{Users’ contributions}}}}).

\sphinxAtStartPar
This chapter briefly reviews the Coq libraries whose contents can
also be browsed at \sphinxurl{http://coq.inria.fr/stdlib/}.


\subsubsection{The prelude}
\label{\detokenize{language/coq-library:the-prelude}}
\sphinxAtStartPar
This section lists the basic notions and results which are directly
available in the standard Coq system. Most of these constructions
are defined in the \sphinxcode{\sphinxupquote{Prelude}} module in directory \sphinxcode{\sphinxupquote{theories/Init}}
in the 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.


\paragraph{Notations}
\label{\detokenize{language/coq-library:notations}}\label{\detokenize{language/coq-library:init-notations}}
\sphinxAtStartPar
This module defines the parsing and pretty\sphinxhyphen{}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 
\sphinxAtStartPar
Notation
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Precedence
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Associativity
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \sphinxhyphen{}> \_}}
&
\sphinxAtStartPar
99
&
\sphinxAtStartPar
right
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <\sphinxhyphen{}> \_}}
&
\sphinxAtStartPar
95
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \textbackslash{}/ \_}}
&
\sphinxAtStartPar
85
&
\sphinxAtStartPar
right
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ /\textbackslash{} \_}}
&
\sphinxAtStartPar
80
&
\sphinxAtStartPar
right
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\textasciitilde{} \_}}
&
\sphinxAtStartPar
75
&
\sphinxAtStartPar
right
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ = \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ = \_ = \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ = \_ :> \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <> \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <> \_ :> \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ < \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ > \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <= \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ >= \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ < \_ < \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ < \_ <= \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <= \_ < \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <= \_ <= \_}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ + \_}}
&
\sphinxAtStartPar
50
&
\sphinxAtStartPar
left
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ || \_}}
&
\sphinxAtStartPar
50
&
\sphinxAtStartPar
left
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \sphinxhyphen{} \_}}
&
\sphinxAtStartPar
50
&
\sphinxAtStartPar
left
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ * \_}}
&
\sphinxAtStartPar
40
&
\sphinxAtStartPar
left
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_      \_}}
&
\sphinxAtStartPar
40
&
\sphinxAtStartPar
left
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ / \_}}
&
\sphinxAtStartPar
40
&
\sphinxAtStartPar
left
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{} \_}}
&
\sphinxAtStartPar
35
&
\sphinxAtStartPar
right
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{/ \_}}
&
\sphinxAtStartPar
35
&
\sphinxAtStartPar
right
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \textasciicircum{} \_}}
&
\sphinxAtStartPar
30
&
\sphinxAtStartPar
right
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}


\paragraph{Logic}
\label{\detokenize{language/coq-library:logic}}\label{\detokenize{language/coq-library:coq-library-logic}}
\sphinxAtStartPar
The basic library of Coq comes with the definitions of standard
(intuitionistic) logical connectives (they are defined as inductive
constructions). They are equipped with an appealing syntax enriching the
subclass {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} of the syntactic class {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. The constructs
for \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/coq-library:grammar-token-form}}\sphinxcode{\sphinxupquote{form}}} are:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline

\sphinxAtStartPar
True
&
\sphinxAtStartPar
True
\\
\hline
\sphinxAtStartPar
False
&
\sphinxAtStartPar
False
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\textasciitilde{} {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}
&
\sphinxAtStartPar
not
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}} /\textbackslash{} {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}
&
\sphinxAtStartPar
and
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}} \textbackslash{}/ {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}
&
\sphinxAtStartPar
or
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}} \sphinxhyphen{}> {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}
&
\sphinxAtStartPar
primitive implication
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}} <\sphinxhyphen{}> {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}
&
\sphinxAtStartPar
iff
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{forall {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}, {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}
&
\sphinxAtStartPar
primitive for all
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{exists {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}}}\DUrole{notation-sup}{?}}, {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}
&
\sphinxAtStartPar
ex
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{exists2 {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}}}\DUrole{notation-sup}{?}}, {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}} \& {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}
&
\sphinxAtStartPar
ex2
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
&
\sphinxAtStartPar
eq
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} :> {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}}}}}
&
\sphinxAtStartPar
eq
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Implication is not defined but primitive (it is a non\sphinxhyphen{}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\sphinxhyphen{}order and higher\sphinxhyphen{}order quantification.
\end{sphinxadmonition}


\subparagraph{Propositional Connectives}
\label{\detokenize{language/coq-library:propositional-connectives}}
\index{Connectives@\spxentry{Connectives}}\index{True (term)@\spxentry{True}\spxextra{term}}\index{I (term)@\spxentry{I}\spxextra{term}}\index{False (term)@\spxentry{False}\spxextra{term}}\index{not (term)@\spxentry{not}\spxextra{term}}\index{and (term)@\spxentry{and}\spxextra{term}}\index{conj (term)@\spxentry{conj}\spxextra{term}}\index{proj1 (term)@\spxentry{proj1}\spxextra{term}}\index{proj2 (term)@\spxentry{proj2}\spxextra{term}}\index{or (term)@\spxentry{or}\spxextra{term}}\index{or\_introl (term)@\spxentry{or\_introl}\spxextra{term}}\index{or\_intror (term)@\spxentry{or\_intror}\spxextra{term}}\index{iff (term)@\spxentry{iff}\spxextra{term}}\index{IF\_then\_else (term)@\spxentry{IF\_then\_else}\spxextra{term}}\ignorespaces 
\sphinxAtStartPar
First, we find propositional calculus connectives:

\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}{|} \PYG{n}{or\PYGZus{}introl} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)}
\PYG{o}{|} \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}


\subparagraph{Quantifiers}
\label{\detokenize{language/coq-library:quantifiers}}
\index{Quantifiers@\spxentry{Quantifiers}}\index{all (term)@\spxentry{all}\spxextra{term}}\index{ex (term)@\spxentry{ex}\spxextra{term}}\index{exists (term)@\spxentry{exists}\spxextra{term}}\index{ex\_intro (term)@\spxentry{ex\_intro}\spxextra{term}}\index{ex2 (term)@\spxentry{ex2}\spxextra{term}}\index{exists2 (term)@\spxentry{exists2}\spxextra{term}}\index{ex\_intro2 (term)@\spxentry{ex\_intro2}\spxextra{term}}\ignorespaces 
\sphinxAtStartPar
Then we find first\sphinxhyphen{}order quantifiers:

\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}

\sphinxAtStartPar
The following abbreviations are allowed:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{exists x:A, P}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ex A (fun x:A => P)}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{exists x, P}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ex \_ (fun x => P)}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{exists2 x:A, P \& Q}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ex2 A (fun x:A => P) (fun x:A => Q)}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{exists2 x, P \& Q}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ex2 \_ (fun x => P) (fun x => Q)}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\sphinxAtStartPar
The type annotation \sphinxcode{\sphinxupquote{:A}} can be omitted when \sphinxcode{\sphinxupquote{A}} can be
synthesized by the system.


\subparagraph{Equality}
\label{\detokenize{language/coq-library:equality}}\label{\detokenize{language/coq-library:coq-equality}}
\index{Equality@\spxentry{Equality}}\index{eq (term)@\spxentry{eq}\spxextra{term}}\index{eq\_refl (term)@\spxentry{eq\_refl}\spxextra{term}}\ignorespaces 
\sphinxAtStartPar
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\sphinxhyphen{}Mohring, is equivalent to
define \sphinxcode{\sphinxupquote{eq}} as the smallest reflexive relation, and it is also
equivalent to Leibniz' equality.

\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}


\subparagraph{Lemmas}
\label{\detokenize{language/coq-library:lemmas}}
\sphinxAtStartPar
Finally, a few easy lemmas are provided.

\index{absurd (term)@\spxentry{absurd}\spxextra{term}}\index{eq\_sym (term)@\spxentry{eq\_sym}\spxextra{term}}\index{eq\_trans (term)@\spxentry{eq\_trans}\spxextra{term}}\index{f\_equal (term)@\spxentry{f\_equal}\spxextra{term}}\index{sym\_not\_eq (term)@\spxentry{sym\_not\_eq}\spxextra{term}}\index{eq\_ind\_r (term)@\spxentry{eq\_ind\_r}\spxextra{term}}\index{eq\_rec\_r (term)@\spxentry{eq\_rec\_r}\spxextra{term}}\index{eq\_rect (term)@\spxentry{eq\_rect}\spxextra{term}}\index{eq\_rect\_r (term)@\spxentry{eq\_rect\_r}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-4}}}
\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)@\spxentry{f\_equal2 ... f\_equal5}\spxextra{term}}\ignorespaces 
\sphinxAtStartPar
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.

\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}


\paragraph{Datatypes}
\label{\detokenize{language/coq-library:datatypes}}\label{\detokenize{language/coq-library:id1}}
\index{Datatypes@\spxentry{Datatypes}}\ignorespaces 
\sphinxAtStartPar
In the basic library, we find in \sphinxcode{\sphinxupquote{Datatypes.v}} the definition
of the basic data\sphinxhyphen{}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}}}}).  The constructs for \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/coq-library:grammar-token-specif}}\sphinxcode{\sphinxupquote{specif}}} are:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} * {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}}}}}
&
\sphinxAtStartPar
prod
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} + {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}}}}}
&
\sphinxAtStartPar
sum
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} + \DUrole{curlies}{\{ {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} \}}}}}
&
\sphinxAtStartPar
sumor
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} \}} + \DUrole{curlies}{\{ {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} \}}}}}
&
\sphinxAtStartPar
sumbool
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} | {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}} \}}}}}
&
\sphinxAtStartPar
sig
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} | {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}} \& {\hyperref[\detokenize{language/coq-library:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}} \}}}}}
&
\sphinxAtStartPar
sig2
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} \& {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} \}}}}}
&
\sphinxAtStartPar
sigT
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} \& {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} \& {\hyperref[\detokenize{language/coq-library:grammar-token-specif}]{\sphinxcrossref{\DUrole{hole}{specif}}}} \}}}}}
&
\sphinxAtStartPar
sigT2
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\sphinxAtStartPar
The notation for pairs (elements of type prod) is: \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}, {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}


\subparagraph{Programming}
\label{\detokenize{language/coq-library:programming}}
\index{Programming@\spxentry{Programming}}\index{unit (term)@\spxentry{unit}\spxextra{term}}\index{tt (term)@\spxentry{tt}\spxextra{term}}\index{bool (term)@\spxentry{bool}\spxextra{term}}\index{true (term)@\spxentry{true}\spxextra{term}}\index{false (term)@\spxentry{false}\spxextra{term}}\index{nat (term)@\spxentry{nat}\spxextra{term}}\index{O (term)@\spxentry{O}\spxextra{term}}\index{S (term)@\spxentry{S}\spxextra{term}}\index{option (term)@\spxentry{option}\spxextra{term}}\index{Some (term)@\spxentry{Some}\spxextra{term}}\index{None (term)@\spxentry{None}\spxextra{term}}\index{identity (term)@\spxentry{identity}\spxextra{term}}\index{refl\_identity (term)@\spxentry{refl\_identity}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-7}}}
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{unit} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{tt}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{bool} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n+nb+bp}{true} \PYG{o}{|} \PYG{n+nb+bp}{false}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{nat} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{O} \PYG{o}{|} \PYG{n}{S} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{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}{|} \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}

\sphinxAtStartPar
Note that zero is the letter \sphinxcode{\sphinxupquote{O}}, and \sphinxstyleemphasis{not} the numeral \sphinxcode{\sphinxupquote{0}}.

\sphinxAtStartPar
The predicate \sphinxcode{\sphinxupquote{identity}} is logically
equivalent to equality but it lives in sort \sphinxcode{\sphinxupquote{Type}}.
It is mainly maintained for compatibility.

\sphinxAtStartPar
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)@\spxentry{sum}\spxextra{term}}\index{A+B (term)@\spxentry{A+B}\spxextra{term}}\index{+ (term)@\spxentry{+}\spxextra{term}}\index{inl (term)@\spxentry{inl}\spxextra{term}}\index{inr (term)@\spxentry{inr}\spxextra{term}}\index{prod (term)@\spxentry{prod}\spxextra{term}}\index{A*B (term)@\spxentry{A*B}\spxextra{term}}\index{* (term)@\spxentry{*}\spxextra{term}}\index{pair (term)@\spxentry{pair}\spxextra{term}}\index{fst (term)@\spxentry{fst}\spxextra{term}}\index{snd (term)@\spxentry{snd}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-8}}}
\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}{|} \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}{|} \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}{|} \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}

\sphinxAtStartPar
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{||}}), \sphinxcode{\sphinxupquote{xorb}}, \sphinxcode{\sphinxupquote{implb}} and \sphinxcode{\sphinxupquote{negb}}.


\paragraph{Specification}
\label{\detokenize{language/coq-library:specification}}\label{\detokenize{language/coq-library:id2}}
\sphinxAtStartPar
The following notions defined in module \sphinxcode{\sphinxupquote{Specif.v}} allow to build new data\sphinxhyphen{}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}}}}.

\sphinxAtStartPar
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}{\sphinxhyphen{}>}\DUrole{keyword,type}{Prop}}}, the construct
\sphinxcode{\sphinxupquote{\DUrole{operator}{\{}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A} \DUrole{operator}{|} \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}}}.

\sphinxAtStartPar
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\sphinxhyphen{}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)@\spxentry{\sphinxleftcurlybrace{}x:A \textbar{} P x\sphinxrightcurlybrace{}}\spxextra{term}}\index{sig (term)@\spxentry{sig}\spxextra{term}}\index{exist (term)@\spxentry{exist}\spxextra{term}}\index{sig2 (term)@\spxentry{sig2}\spxextra{term}}\index{exist2 (term)@\spxentry{exist2}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-9}}}
\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}

\sphinxAtStartPar
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)@\spxentry{\sphinxleftcurlybrace{}x:A \& P x\sphinxrightcurlybrace{}}\spxextra{term}}\index{sigT (term)@\spxentry{sigT}\spxextra{term}}\index{existT (term)@\spxentry{existT}\spxextra{term}}\index{sigT2 (term)@\spxentry{sigT2}\spxextra{term}}\index{existT2 (term)@\spxentry{existT2}\spxextra{term}}\index{projT1 (term)@\spxentry{projT1}\spxextra{term}}\index{projT2 (term)@\spxentry{projT2}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-10}}}
\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}

\sphinxAtStartPar
A related non\sphinxhyphen{}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)@\spxentry{sumbool}\spxextra{term}}\index{left (term)@\spxentry{left}\spxextra{term}}\index{right (term)@\spxentry{right}\spxextra{term}}\index{\sphinxleftcurlybrace{}A\sphinxrightcurlybrace{}+\sphinxleftcurlybrace{}B\sphinxrightcurlybrace{} (term)@\spxentry{\sphinxleftcurlybrace{}A\sphinxrightcurlybrace{}+\sphinxleftcurlybrace{}B\sphinxrightcurlybrace{}}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-11}}}
\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}{|} \PYG{k}{right} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
This \sphinxcode{\sphinxupquote{sumbool}} construct may be used as a kind of indexed boolean
data\sphinxhyphen{}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)@\spxentry{sumor}\spxextra{term}}\index{inleft (term)@\spxentry{inleft}\spxextra{term}}\index{inright (term)@\spxentry{inright}\spxextra{term}}\index{A+\sphinxleftcurlybrace{}B\sphinxrightcurlybrace{} (term)@\spxentry{A+\sphinxleftcurlybrace{}B\sphinxrightcurlybrace{}}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-12}}}
\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}{|} \PYG{n}{inleft} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)}
\PYG{o}{|} \PYG{n}{inright} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
We may define variants of the axiom of choice, like in Martin\sphinxhyphen{}Löf's
Intuitionistic Type Theory.

\index{Choice (term)@\spxentry{Choice}\spxextra{term}}\index{Choice2 (term)@\spxentry{Choice2}\spxextra{term}}\index{bool\_choice (term)@\spxentry{bool\_choice}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-13}}}
\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}{|} \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}{|} \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{n}{bool} \PYG{o}{|}
   \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}

\sphinxAtStartPar
The next construct builds a sum between a data\sphinxhyphen{}type \sphinxcode{\sphinxupquote{\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,type}{Type}}} and
an exceptional value encoding errors:

\index{Exc (term)@\spxentry{Exc}\spxextra{term}}\index{value (term)@\spxentry{value}\spxextra{term}}\index{error (term)@\spxentry{error}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-14}}}
\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}

\sphinxAtStartPar
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)@\spxentry{False\_rect}\spxextra{term}}\index{False\_rec (term)@\spxentry{False\_rec}\spxextra{term}}\index{eq\_rect (term)@\spxentry{eq\_rect}\spxextra{term}}\index{absurd\_set (term)@\spxentry{absurd\_set}\spxextra{term}}\index{and\_rect (term)@\spxentry{and\_rect}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-15}}}
\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}


\paragraph{Basic Arithmetic}
\label{\detokenize{language/coq-library:basic-arithmetic}}
\sphinxAtStartPar
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}

\sphinxAtStartPar
The following example is not part of the standard library, but it
shows the usage of the notations:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{even} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
 \PYG{o}{|} \PYG{l+m+mi}{1} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
 \PYG{o}{|} \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)@\spxentry{eq\_S}\spxextra{term}}\index{pred (term)@\spxentry{pred}\spxextra{term}}\index{pred\_Sn (term)@\spxentry{pred\_Sn}\spxextra{term}}\index{eq\_add\_S (term)@\spxentry{eq\_add\_S}\spxextra{term}}\index{not\_eq\_S (term)@\spxentry{not\_eq\_S}\spxextra{term}}\index{IsSucc (term)@\spxentry{IsSucc}\spxextra{term}}\index{O\_S (term)@\spxentry{O\_S}\spxextra{term}}\index{n\_Sn (term)@\spxentry{n\_Sn}\spxextra{term}}\index{plus (term)@\spxentry{plus}\spxextra{term}}\index{plus\_n\_O (term)@\spxentry{plus\_n\_O}\spxextra{term}}\index{plus\_n\_Sm (term)@\spxentry{plus\_n\_Sm}\spxextra{term}}\index{mult (term)@\spxentry{mult}\spxextra{term}}\index{mult\_n\_O (term)@\spxentry{mult\_n\_O}\spxextra{term}}\index{mult\_n\_Sm (term)@\spxentry{mult\_n\_Sm}\spxextra{term}}\ignorespaces 
\sphinxAtStartPar
Now comes the content of module \sphinxcode{\sphinxupquote{Peano}}:

\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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
 \PYG{o}{|} \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{n}{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{n}{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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{False}
 \PYG{o}{|} \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{n}{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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
 \PYG{o}{|} \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{n}{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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
 \PYG{o}{|} \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{n}{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{n}{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}

\sphinxAtStartPar
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)@\spxentry{le}\spxextra{term}}\index{le\_n (term)@\spxentry{le\_n}\spxextra{term}}\index{le\_S (term)@\spxentry{le\_S}\spxextra{term}}\index{lt (term)@\spxentry{lt}\spxextra{term}}\index{ge (term)@\spxentry{ge}\spxextra{term}}\index{gt (term)@\spxentry{gt}\spxextra{term}}\ignorespaces 
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{le} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{|} \PYG{n}{le\PYGZus{}n} \PYG{o}{:} \PYG{n}{le} \PYG{n}{n} \PYG{n}{n}
\PYG{o}{|} \PYG{n}{le\PYGZus{}S} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{:}\PYG{n}{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{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{n}{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{n}{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{n}{nat}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{m} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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)@\spxentry{nat\_case}\spxextra{term}}\index{nat\_double\_ind (term)@\spxentry{nat\_double\_ind}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-18}}}
\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{n}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{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{n}{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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{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{n}{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{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{R} \PYG{n}{n} \PYG{n}{m}\PYG{o}{.}
\end{sphinxVerbatim}


\paragraph{Well\sphinxhyphen{}founded recursion}
\label{\detokenize{language/coq-library:well-founded-recursion}}
\sphinxAtStartPar
The basic library contains the basics of well\sphinxhyphen{}founded recursion and
well\sphinxhyphen{}founded induction, in module \sphinxcode{\sphinxupquote{Wf.v}}.

\index{Well foundedness@\spxentry{Well foundedness}}\index{Recursion@\spxentry{Recursion}}\index{Well founded induction@\spxentry{Well founded induction}}\index{Acc (term)@\spxentry{Acc}\spxextra{term}}\index{Acc\_inv (term)@\spxentry{Acc\_inv}\spxextra{term}}\index{Acc\_rect (term)@\spxentry{Acc\_rect}\spxextra{term}}\index{well\_founded (term)@\spxentry{well\_founded}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-19}}}
\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}

\sphinxAtStartPar
The automatically generated scheme \sphinxcode{\sphinxupquote{Acc\_rect}}
can be used to define functions by fixpoints using
well\sphinxhyphen{}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)@\spxentry{Fix\_F}\spxextra{term}}\index{Fix\_eq (term)@\spxentry{Fix\_eq}\spxextra{term}}\index{Fix\_F\_inv (term)@\spxentry{Fix\_F\_inv}\spxextra{term}}\index{Fix\_F\_eq (term)@\spxentry{Fix\_F\_eq}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-20}}}
\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}


\paragraph{Accessing the Type level}
\label{\detokenize{language/coq-library:accessing-the-type-level}}
\sphinxAtStartPar
The standard library includes \sphinxcode{\sphinxupquote{Type}} level definitions of counterparts of some
logic concepts and basic lemmas about them.

\sphinxAtStartPar
The module \sphinxcode{\sphinxupquote{Datatypes}} defines \sphinxcode{\sphinxupquote{identity}}, which is the \sphinxcode{\sphinxupquote{Type}} level counterpart
of equality:

\index{identity (term)@\spxentry{identity}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-21}}}
\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{n}{a}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
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)@\spxentry{notT}\spxextra{term}}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-22}}}
\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}


\paragraph{Tactics}
\label{\detokenize{language/coq-library:tactics}}
\sphinxAtStartPar
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}}.


\subsubsection{The standard library}
\label{\detokenize{language/coq-library:the-standard-library}}

\paragraph{Survey}
\label{\detokenize{language/coq-library:survey}}
\sphinxAtStartPar
The rest of the standard library is structured into the following
subdirectories:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Logic} : Classical logic and dependent equality

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Arith} : Basic Peano arithmetic

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{PArith} : Basic positive integer arithmetic

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{NArith} : Basic binary natural number arithmetic

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{ZArith} : Basic relative integer arithmetic

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Numbers} : Various approaches to natural, integer and cyclic numbers (currently axiomatically and on top of 2\textasciicircum{}31 binary words)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Bool} : Booleans (basic functions and results)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Lists} : Monomorphic and polymorphic lists (basic functions and results), Streams (infinite sequences defined with co\sphinxhyphen{}inductive types)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Sets} : Sets (classical, constructive, finite, infinite, power set, etc.)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{FSets} : Specification and implementations of finite sets and finite maps (by lists and by AVL trees)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Reals} : Axiomatization of real numbers (classical, basic functions, integer part, fractional part, limit, derivative, Cauchy series, power series and results,...)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Floats} : Machine implementation of floating\sphinxhyphen{}point arithmetic (for the binary64 format)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Relations} : Relations (definitions and basic results)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Sorting} : Sorted list (basic definitions and heapsort correctness)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Strings} : 8\sphinxhyphen{}bits characters and strings

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Wellfounded} : Well\sphinxhyphen{}founded relations (basic results)

\end{itemize}

\sphinxAtStartPar
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}}}}).

\sphinxAtStartPar
The different modules of the Coq standard library are documented
online at \sphinxurl{https://coq.inria.fr/stdlib}.


\paragraph{Peano’s arithmetic (nat)}
\label{\detokenize{language/coq-library:peanos-arithmetic-nat}}
\index{Peano's arithmetic@\spxentry{Peano's arithmetic}}\index{nat\_scope@\spxentry{nat\_scope}}\ignorespaces 
\sphinxAtStartPar
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}}.

\sphinxAtStartPar
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 
\sphinxAtStartPar
Notation
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Interpretation
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ < \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{lt}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <= \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{le}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ > \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{gt}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ >= \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ge}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y < z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y /\textbackslash{} y < z}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y <= z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y /\textbackslash{} y <= z}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y < z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y /\textbackslash{} y < z}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y <= z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y /\textbackslash{} y <= z}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ + \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{plus}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \sphinxhyphen{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{minus}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ * \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{mult}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}


\paragraph{Notations for integer arithmetic}
\label{\detokenize{language/coq-library:notations-for-integer-arithmetic}}
\index{Arithmetical notations@\spxentry{Arithmetical notations}}\index{+ (term)@\spxentry{+}\spxextra{term}}\index{* (term)@\spxentry{*}\spxextra{term}}\index{\sphinxhyphen{} (term)@\spxentry{\sphinxhyphen{}}\spxextra{term}}\index{singel: / (term)@\spxentry{singel: /}\spxextra{term}}\index{<= (term)@\spxentry{<=}\spxextra{term}}\index{>= (term)@\spxentry{>=}\spxextra{term}}\index{< (term)@\spxentry{<}\spxextra{term}}\index{> (term)@\spxentry{>}\spxextra{term}}\index{?= (term)@\spxentry{?=}\spxextra{term}}\index{mod (term)@\spxentry{mod}\spxextra{term}}\ignorespaces 
\sphinxAtStartPar
The following table describes the syntax of expressions
for integer arithmetic. 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 
\sphinxAtStartPar
Notation
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Interpretation
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Precedence
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Associativity
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ < \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.lt}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <= \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.le}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ > \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.gt}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ >= \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.ge}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y < z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y /\textbackslash{} y < z}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y <= z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y /\textbackslash{} y <= z}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y < z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y /\textbackslash{} y < z}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y <= z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y /\textbackslash{} y <= z}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ ?= \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.compare}}
&
\sphinxAtStartPar
70
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ + \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.add}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \sphinxhyphen{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.sub}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ * \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.mul}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ / \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.div}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ mod \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.modulo}}
&
\sphinxAtStartPar
40
&
\sphinxAtStartPar
no
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.opp}}
&&\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \textasciicircum{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Z.pow}}
&&\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\begin{sphinxadmonition}{note}{Example}

\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}{ring\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}{zify\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}{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}


\paragraph{Real numbers library}
\label{\detokenize{language/coq-library:real-numbers-library}}

\subparagraph{Notations for real numbers}
\label{\detokenize{language/coq-library:notations-for-real-numbers}}
\sphinxAtStartPar
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 arithmetic. The inverse function was added.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
Notation
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Interpretation
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ < \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rlt}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <= \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rle}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ > \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rgt}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ >= \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rge}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y < z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y /\textbackslash{} y < z}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y <= z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x < y /\textbackslash{} y <= z}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y < z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y /\textbackslash{} y < z}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y <= z}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{x <= y /\textbackslash{} y <= z}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ + \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rplus}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \sphinxhyphen{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rminus}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ * \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rmult}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ / \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rdiv}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Ropp}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{/ \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Rinv}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \textasciicircum{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{pow}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Reals}\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}


\subparagraph{Some tactics for real numbers}
\label{\detokenize{language/coq-library:some-tactics-for-real-numbers}}
\sphinxAtStartPar
In addition to the powerful \sphinxcode{\sphinxupquote{ring}}, \sphinxcode{\sphinxupquote{field}} and \sphinxcode{\sphinxupquote{lra}}
tactics (see Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}), there are also:
\index{discrR (tactic)@\spxentry{discrR}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/coq-library:coq:tacn.discrR}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{discrR}}}}
\sphinxAtStartPar
Proves that two real integer constants are different.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{split\_Rabs (tactic)@\spxentry{split\_Rabs}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/coq-library:coq:tacn.split_Rabs}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{split\_Rabs}}}}
\sphinxAtStartPar
Allows unfolding the \sphinxcode{\sphinxupquote{Rabs}} constant and splits corresponding conjunctions.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \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}{goal} \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 (tactic)@\spxentry{split\_Rmult}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/coq-library:coq:tacn.split_Rmult}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{split\_Rmult}}}}
\sphinxAtStartPar
Splits a condition that a product is non null into subgoals
corresponding to the condition on each operand of the product.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goals}
      
      \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}{goal} \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}{goal} \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}

\sphinxAtStartPar
These tactics has been written with the tactic language \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$
described in Chapter {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac}}}}.


\paragraph{List library}
\label{\detokenize{language/coq-library:list-library}}
\index{Notations for lists@\spxentry{Notations for lists}}\index{length (term)@\spxentry{length}\spxextra{term}}\index{head (term)@\spxentry{head}\spxextra{term}}\index{tail (term)@\spxentry{tail}\spxextra{term}}\index{app (term)@\spxentry{app}\spxextra{term}}\index{rev (term)@\spxentry{rev}\spxextra{term}}\index{nth (term)@\spxentry{nth}\spxextra{term}}\index{map (term)@\spxentry{map}\spxextra{term}}\index{flat\_map (term)@\spxentry{flat\_map}\spxextra{term}}\index{fold\_left (term)@\spxentry{fold\_left}\spxextra{term}}\index{fold\_right (term)@\spxentry{fold\_right}\spxextra{term}}\ignorespaces 
\sphinxAtStartPar
Some elementary operations on polymorphic lists are defined here.
They can be accessed by requiring module \sphinxcode{\sphinxupquote{List}}.

\sphinxAtStartPar
It defines the following notions:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{length}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{head}} : first element (with default)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{tail}} : all but first element

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{app}} : concatenation

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{rev}} : reverse

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{nth}} : accessing n\sphinxhyphen{}th element (with default)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{map}} : applying a function

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{flat\_map}} : applying a function returning lists

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{fold\_left}} : iterator (from head to tail)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{fold\_right}} : iterator (from tail to head)

\end{itemize}

\sphinxAtStartPar
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 
\sphinxAtStartPar
Notation
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Interpretation
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Precedence
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Associativity
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ ++ \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{app}}
&
\sphinxAtStartPar
60
&
\sphinxAtStartPar
right
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ :: \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{cons}}
&
\sphinxAtStartPar
60
&
\sphinxAtStartPar
right
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}


\paragraph{Floats library}
\label{\detokenize{language/coq-library:floats-library}}\label{\detokenize{language/coq-library:id3}}
\sphinxAtStartPar
The library of primitive floating\sphinxhyphen{}point arithmetic can be loaded by
requiring module \sphinxcode{\sphinxupquote{Floats}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Floats}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
It exports the module \sphinxcode{\sphinxupquote{PrimFloat}} that provides a primitive type
named \sphinxcode{\sphinxupquote{float}}, defined in the kernel (see section {\hyperref[\detokenize{language/core/primitive:primitive-floats}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Floats}}}}),
as well as two variant types \sphinxcode{\sphinxupquote{float\_comparison}} and \sphinxcode{\sphinxupquote{float\_class}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{float}\PYG{o}{.}
    \PYG{o}{*}\PYG{o}{*}\PYG{o}{*} \PYG{o}{[} \PYG{n}{float} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{]}

\PYG{k+kn}{Print} \PYG{n}{float\PYGZus{}comparison}\PYG{o}{.}
    \PYG{n}{Variant} \PYG{n}{float\PYGZus{}comparison} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
        \PYG{n}{FEq} \PYG{o}{:} \PYG{n}{float\PYGZus{}comparison}
      \PYG{o}{|} \PYG{n}{FLt} \PYG{o}{:} \PYG{n}{float\PYGZus{}comparison}
      \PYG{o}{|} \PYG{n}{FGt} \PYG{o}{:} \PYG{n}{float\PYGZus{}comparison}
      \PYG{o}{|} \PYG{n}{FNotComparable} \PYG{o}{:} \PYG{n}{float\PYGZus{}comparison}\PYG{o}{.}

\PYG{k+kn}{Print} \PYG{n}{float\PYGZus{}class}\PYG{o}{.}
    \PYG{n}{Variant} \PYG{n}{float\PYGZus{}class} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
        \PYG{n}{PNormal} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}
      \PYG{o}{|} \PYG{n}{NNormal} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}
      \PYG{o}{|} \PYG{n}{PSubn} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}
      \PYG{o}{|} \PYG{n}{NSubn} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}
      \PYG{o}{|} \PYG{n}{PZero} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}
      \PYG{o}{|} \PYG{n}{NZero} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}
      \PYG{o}{|} \PYG{n}{PInf} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}
      \PYG{o}{|} \PYG{n}{NInf} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}
      \PYG{o}{|} \PYG{n}{NaN} \PYG{o}{:} \PYG{n}{float\PYGZus{}class}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
It then defines the primitive operators below, using the processor
floating\sphinxhyphen{}point operators for binary64 in rounding\sphinxhyphen{}to\sphinxhyphen{}nearest even:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{abs}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{opp}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{sub}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{add}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{mul}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{div}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{sqrt}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{compare}} : compare two floats and return a \sphinxcode{\sphinxupquote{float\_comparison}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{classify}} : analyze a float and return a \sphinxcode{\sphinxupquote{float\_class}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{of\_int63}} : round a primitive integer and convert it into a float

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{normfr\_mantissa}} : take a float in \sphinxcode{\sphinxupquote{{[}0.5; 1.0)}} and return its mantissa

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{frshiftexp}} : convert a float to fractional part in \sphinxcode{\sphinxupquote{{[}0.5; 1.0)}} and integer part

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ldshiftexp}} : multiply a float by an integral power of \sphinxcode{\sphinxupquote{2}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{next\_up}} : return the next float towards positive infinity

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{next\_down}} : return the next float towards negative infinity

\end{itemize}

\sphinxAtStartPar
For special floating\sphinxhyphen{}point values, the following constants are also
defined:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{zero}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{neg\_zero}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{one}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{two}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{infinity}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{neg\_infinity}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{nan}} : Not a Number (assumed to be unique: the "payload" of NaNs is ignored)

\end{itemize}

\sphinxAtStartPar
The following table shows the notations available when opening scope
\sphinxcode{\sphinxupquote{float\_scope}}.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
Notation
&\sphinxstyletheadfamily 
\sphinxAtStartPar
Interpretation
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{opp}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ \sphinxhyphen{} \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{sub}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ + \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{add}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ * \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{mul}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ / \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{div}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ =? \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{eqb}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <? \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ltb}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ <=? \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{leb}}
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\_ ?= \_}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{compare}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\sphinxAtStartPar
Floating\sphinxhyphen{}point constants are parsed and pretty\sphinxhyphen{}printed as (17\sphinxhyphen{}digit)
decimal constants. This ensures that the composition
\(\text{parse} \circ \text{print}\) amounts to the identity.
\index{The constant ‘number’ is not a binary64 floating\sphinxhyphen{}point value. A closest value ‘number’ will be used and unambiguously printed ‘number’. {[}inexact\sphinxhyphen{}float,parsing{]} (warning)@\spxentry{The constant ‘number’ is not a binary64 floating\sphinxhyphen{}point value. A closest value ‘number’ will be used and unambiguously printed ‘number’. {[}inexact\sphinxhyphen{}float,parsing{]}}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/coq-library:coq:warn.The-constant-_u2018number_u2019-is-not-a-binary64-floating-point-value.-A-closest-value-_u2018number_u2019-will-be-used-and-unambiguously-printed-_u2018number_u2019.-_inexact-float,parsing_}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~constant~{\hyperref[\detokenize{language/core/basic:grammar-token-number}]{\sphinxcrossref{\DUrole{hole}{number}}}}~is~not~a~binary64~floating\sphinxhyphen{}point~value.~A~closest~value~{\hyperref[\detokenize{language/core/basic:grammar-token-number}]{\sphinxcrossref{\DUrole{hole}{number}}}}~will~be~used~and~unambiguously~printed~{\hyperref[\detokenize{language/core/basic:grammar-token-number}]{\sphinxcrossref{\DUrole{hole}{number}}}}.~{[}inexact\sphinxhyphen{}float,parsing{]}}}}}
\sphinxAtStartPar
Not all decimal constants are floating\sphinxhyphen{}point values. This warning
is generated when parsing such a constant (for instance \sphinxcode{\sphinxupquote{0.1}}).

\end{fulllineitems}\end{savenotes}

\index{Printing Float (flag)@\spxentry{Printing Float}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{language/coq-library:coq:flag.Printing-Float}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Float}}}}
\sphinxAtStartPar
Turn this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} off (it is on by default) to deactivate decimal
printing of floating\sphinxhyphen{}point constants. They will then be printed
with an hexadecimal representation.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{float\PYGZus{}scope}\PYG{o}{.}
\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{5}\PYG{o}{.}
    \PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{.}\PYG{l+m+mi}{5}
         \PYG{o}{:} \PYG{n}{float}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{l+m+mi}{1} \PYG{o}{/} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{o}{=} \PYG{n}{infinity}
         \PYG{o}{:} \PYG{n}{float}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{l+m+mi}{1} \PYG{o}{/} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{o}{=} \PYG{n}{neg\PYGZus{}infinity}
         \PYG{o}{:} \PYG{n}{float}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{l+m+mi}{0} \PYG{o}{/} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{o}{=} \PYG{n}{nan}
         \PYG{o}{:} \PYG{n}{float}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{l+m+mi}{0} \PYG{o}{?}\PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{o}{=} \PYG{n}{FEq}
         \PYG{o}{:} \PYG{n}{float\PYGZus{}comparison}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{nan} \PYG{o}{?}\PYG{o}{=} \PYG{n}{nan}\PYG{o}{.}
    \PYG{o}{=} \PYG{n}{FNotComparable}
         \PYG{o}{:} \PYG{n}{float\PYGZus{}comparison}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{next\PYGZus{}down} \PYG{o}{(}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{o}{.}\PYG{l+m+mi}{0000000000000002}
         \PYG{o}{:} \PYG{n}{float}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
The primitive operators are specified with respect to their Gallina
counterpart, using the variant type \sphinxcode{\sphinxupquote{spec\_float}}, and the injection
\sphinxcode{\sphinxupquote{Prim2SF}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{spec\PYGZus{}float}\PYG{o}{.}
    \PYG{n}{Variant} \PYG{n}{spec\PYGZus{}float} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
        \PYG{n}{S754\PYGZus{}zero} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{spec\PYGZus{}float}
      \PYG{o}{|} \PYG{n}{S754\PYGZus{}infinity} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{spec\PYGZus{}float}
      \PYG{o}{|} \PYG{n}{S754\PYGZus{}nan} \PYG{o}{:} \PYG{n}{spec\PYGZus{}float}
      \PYG{o}{|} \PYG{n}{S754\PYGZus{}finite} \PYG{o}{:} \PYG{n}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{positive} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{spec\PYGZus{}float}\PYG{o}{.}
    
    \PYG{k+kn}{Arguments} \PYG{n}{S754\PYGZus{}zero} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{bool\PYGZus{}scope}
    \PYG{k+kn}{Arguments} \PYG{n}{S754\PYGZus{}infinity} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{bool\PYGZus{}scope}
    \PYG{k+kn}{Arguments} \PYG{n}{S754\PYGZus{}finite} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{bool\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{positive\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{Z\PYGZus{}scope}

\PYG{k+kn}{Check} \PYG{n}{Prim2SF}\PYG{o}{.}
    \PYG{n}{Prim2SF}
         \PYG{o}{:} \PYG{n}{float} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{spec\PYGZus{}float}

\PYG{k+kn}{Check} \PYG{n}{mul\PYGZus{}spec}\PYG{o}{.}
    \PYG{n}{mul\PYGZus{}spec}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{float}\PYG{o}{,} \PYG{n}{Prim2SF} \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=} \PYG{n}{SF64mul} \PYG{o}{(}\PYG{n}{Prim2SF} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Prim2SF} \PYG{n}{y}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
For more details on the available definitions and lemmas, see the
online documentation of the \sphinxcode{\sphinxupquote{Floats}} library.


\subsubsection{Users’ contributions}
\label{\detokenize{language/coq-library:users-contributions}}\label{\detokenize{language/coq-library:userscontributions}}
\sphinxAtStartPar
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.


\subsection{Program extraction}
\label{\detokenize{addendum/extraction:program-extraction}}\label{\detokenize{addendum/extraction:extraction}}\label{\detokenize{addendum/extraction::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
\sphinxAtStartPar
Jean\sphinxhyphen{}Christophe Filliâtre and Pierre Letouzey

\end{description}\end{quote}

\sphinxAtStartPar
We present here the Coq extraction commands, used to build certified
and relatively efficient functional programs, extracting them from
either Coq functions or Coq proofs of specifications. The
functional languages available as output are currently OCaml, Haskell
and Scheme. In the following, "ML" will be used (abusively) to refer
to any of the three.

\sphinxAtStartPar
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}}.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{n}{Extraction}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Generating ML Code}
\label{\detokenize{addendum/extraction:generating-ml-code}}
\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
In the following, a qualified identifier {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}
can be used to refer to any kind of Coq global "object" : {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}},
inductive type, inductive constructor or module name.
\end{sphinxadmonition}

\sphinxAtStartPar
The next two commands are meant to be used for rapid preview of
extraction. They both display extracted term(s) inside Coq.
\index{Extraction (command)@\spxentry{Extraction}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.Extraction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\sphinxAtStartPar
Extraction of the mentioned object in the Coq toplevel.

\end{fulllineitems}\end{savenotes}

\index{Recursive Extraction (command)@\spxentry{Recursive Extraction}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Recursive extraction of all the mentioned objects and
all their dependencies in the Coq toplevel.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
All the following commands produce real ML files. User can choose to
produce one monolithic file or one file per Coq library.
\index{Extraction (command)@\spxentry{Extraction}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:id1}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Recursive extraction of all the mentioned objects and all
their dependencies in one monolithic file {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}.
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}\end{savenotes}

\index{Extraction Library (command)@\spxentry{Extraction Library}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Extraction of the whole Coq library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.v}}} to an ML module
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.ml}}}. In case of name clash, identifiers are here renamed
using prefixes \sphinxcode{\sphinxupquote{coq\_}}  or \sphinxcode{\sphinxupquote{Coq\_}} to ensure a session\sphinxhyphen{}independent
renaming.

\end{fulllineitems}\end{savenotes}

\index{Recursive Extraction Library (command)@\spxentry{Recursive Extraction Library}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\sphinxAtStartPar
Extraction of the Coq library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.v}}} and all other modules
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.v}}} depends on.

\end{fulllineitems}\end{savenotes}

\index{Separate Extraction (command)@\spxentry{Separate Extraction}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Recursive extraction of all the mentioned objects and all
their dependencies, just as \sphinxcode{\sphinxupquote{\DUrole{notation}{Extraction {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}},
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}\end{savenotes}


\sphinxAtStartPar
The following command is meant to help automatic testing of
the extraction, see for instance the \sphinxcode{\sphinxupquote{test\sphinxhyphen{}suite}} directory
in the Coq sources.
\index{Extraction TestCompile (command)@\spxentry{Extraction TestCompile}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
All the mentioned objects and all their dependencies are extracted
to a temporary OCaml file, just as in \sphinxcode{\sphinxupquote{Extraction "file"}}. Then
this temporary file and its signature are compiled with the same
OCaml compiler used to built Coq. This command succeeds only
if the extraction and the OCaml compilation succeed. It fails
if the current target language of the extraction is not OCaml.

\end{fulllineitems}\end{savenotes}



\subsubsection{Extraction Options}
\label{\detokenize{addendum/extraction:extraction-options}}

\paragraph{Setting the target language}
\label{\detokenize{addendum/extraction:setting-the-target-language}}\index{Extraction Language (command)@\spxentry{Extraction Language}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.Extraction-Language}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Language~{\hyperref[\detokenize{addendum/extraction:grammar-token-language}]{\sphinxcrossref{\DUrole{hole}{language}}}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{addendum/extraction:grammar-token-language}}}\DUrole{notation}{{\hyperref[\detokenize{addendum/extraction:grammar-token-language}]{\sphinxcrossref{\DUrole{hole}{language}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{OCaml}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Haskell}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{Scheme}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\sphinxcode{\sphinxupquote{}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{|}}}\DUrole{prodn-cell-production}{\DUrole{notation}{JSON}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
The ability to fix target language is the first and most important
of the extraction options. Default is \sphinxcode{\sphinxupquote{OCaml}}.

\sphinxAtStartPar
The JSON output is mostly for development or debugging:
it contains the raw ML term produced as an intermediary target.

\end{fulllineitems}\end{savenotes}



\paragraph{Inlining and optimizations}
\label{\detokenize{addendum/extraction:inlining-and-optimizations}}
\sphinxAtStartPar
Since 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 OCaml program. The optimizations can be split in two
groups: the type\sphinxhyphen{}preserving ones (essentially constant inlining and
reductions) and the non type\sphinxhyphen{}preserving ones (some function
abstractions of dummy types are removed when it is deemed safe in order
to have more elegant types). Therefore some {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} may not appear in the
resulting monolithic OCaml program. In the case of modular extraction,
even if some inlining is done, the inlined constants are nevertheless
printed, to ensure session\sphinxhyphen{}independent programs.

\sphinxAtStartPar
Concerning Haskell, type\sphinxhyphen{}preserving optimizations are less useful
because of laziness. We still make some optimizations, for example in
order to produce more readable code.

\sphinxAtStartPar
The type\sphinxhyphen{}preserving optimizations are controlled by the following Coq flags
and commands:
\index{Extraction Optimize (flag)@\spxentry{Extraction Optimize}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.Extraction-Optimize}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Optimize}}}}
\sphinxAtStartPar
Default is on. This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls all type\sphinxhyphen{}preserving optimizations made on
the ML terms (mostly reduction of dummy beta/iota redexes, but also
simplifications on Cases, etc). Turn this flag off if you want a
ML term as close as possible to the Coq term.

\end{fulllineitems}\end{savenotes}

\index{Extraction Conservative Types (flag)@\spxentry{Extraction Conservative Types}\spxextra{flag}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Default is off. This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} controls the non type\sphinxhyphen{}preserving optimizations
made on ML terms (which try to avoid function abstraction of dummy
types). Turn this flag 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}\end{savenotes}

\index{Extraction KeepSingleton (flag)@\spxentry{Extraction KeepSingleton}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.Extraction-KeepSingleton}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~KeepSingleton}}}}
\sphinxAtStartPar
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 {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} allows disabling this
optimization when one wishes to preserve the inductive structure of types.

\end{fulllineitems}\end{savenotes}

\index{Extraction AutoInline (flag)@\spxentry{Extraction AutoInline}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.Extraction-AutoInline}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~AutoInline}}}}
\sphinxAtStartPar
Default is on. The extraction mechanism inlines the {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{bodies}}}} of
some defined {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{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 {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} off.

\end{fulllineitems}\end{savenotes}

\index{Extraction Inline (command)@\spxentry{Extraction Inline}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
In addition to the automatic inline feature, the {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}}
mentioned by this command will always be inlined during extraction.

\end{fulllineitems}\end{savenotes}

\index{Extraction NoInline (command)@\spxentry{Extraction NoInline}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Conversely, the constants mentioned by this command will
never be inlined during extraction.

\end{fulllineitems}\end{savenotes}

\index{Print Extraction Inline (command)@\spxentry{Print Extraction Inline}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Prints the current state of the table recording the custom inlinings
declared by the two previous commands.

\end{fulllineitems}\end{savenotes}

\index{Reset Extraction Inline (command)@\spxentry{Reset Extraction Inline}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Empties the table recording the custom inlinings (see the
previous commands).

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
\sphinxstylestrong{Inlining and printing of a constant declaration:}

\sphinxAtStartPar
The user can explicitly ask for a {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} to be extracted by two means:
\begin{itemize}
\item {} 
\sphinxAtStartPar
by mentioning it on the extraction command line

\item {} 
\sphinxAtStartPar
by extracting the whole Coq module of this {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}}.

\end{itemize}

\sphinxAtStartPar
In both cases, the declaration of this {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} will be present in the
produced file. But this same {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} may or may not be inlined in
the following terms, depending on the automatic/custom inlining mechanism.

\sphinxAtStartPar
For the {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} non\sphinxhyphen{}explicitly required but needed for dependency
reasons, there are two cases:
\begin{itemize}
\item {} 
\sphinxAtStartPar
If an inlining decision is taken, whether automatically or not,
all occurrences of this {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} are replaced by its extracted {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}},
and this {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} is not declared in the generated file.

\item {} 
\sphinxAtStartPar
If no inlining decision is taken, the {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}} is normally
declared in the produced file.

\end{itemize}


\paragraph{Extra elimination of useless arguments}
\label{\detokenize{addendum/extraction:extra-elimination-of-useless-arguments}}
\sphinxAtStartPar
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 (command)@\spxentry{Extraction Implicit}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\DUrole{hole}{integer}}}}}}}\DUrole{notation-sup}{*}}~{]}}}}}
\sphinxAtStartPar
Declares some arguments of
{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} as implicit, meaning that they are useless in extracted code.
The extracted code will omit these arguments.
Here {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} can be
any function or inductive constructor, and the {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}s are
the names of the useless arguments.  Arguments can can also be
identified positionally by {\hyperref[\detokenize{language/core/basic:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}s starting from 1.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
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 flag:
\index{Extraction SafeImplicits (flag)@\spxentry{Extraction SafeImplicits}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.Extraction-SafeImplicits}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~SafeImplicits}}}}
\sphinxAtStartPar
Default is on. When this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} 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}\end{savenotes}



\paragraph{Realizing axioms}
\label{\detokenize{addendum/extraction:realizing-axioms}}
\sphinxAtStartPar
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\sphinxhyphen{}terminating extracted terms.

\sphinxAtStartPar
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 (command)@\spxentry{Extract Constant}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{tv}}$}}}}}\DUrole{notation-sup}{*}}~=>~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}}}
\sphinxAtStartPar
Give an ML extraction for the given {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constant}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{tv}}$}}}}}}}}] \leavevmode
\sphinxAtStartPar
If the type scheme axiom is an arity (a sequence of products followed
by a sort), then some type
variables have to be given (as quoted strings).

\sphinxAtStartPar
The number of type variables is checked by the system. For example:

\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}

\end{description}

\end{fulllineitems}\end{savenotes}

\index{Extract Inlined Constant (command)@\spxentry{Extract Inlined Constant}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~=>~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}}}
\sphinxAtStartPar
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:}
\sphinxAtStartPar
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}\end{savenotes}


\begin{sphinxadmonition}{caution}{Caution:}
\sphinxAtStartPar
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}

\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}

\sphinxAtStartPar
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\sphinxhyphen{}terminating extracted terms.

\sphinxAtStartPar
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.


\paragraph{Realizing inductive types}
\label{\detokenize{addendum/extraction:realizing-inductive-types}}
\sphinxAtStartPar
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 Coq one. The syntax is the following:
\index{Extract Inductive (command)@\spxentry{Extract Inductive}\spxextra{command}}

\begin{savenotes}\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~=>~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}\DUrole{notation-sup}{*}}~{]}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{match}}$}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Give an ML extraction for the given inductive type. You must specify
extractions for the type itself (the initial \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}}) and all its
constructors (the \sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeated-alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}\DUrole{notation-sup}{*}} {]}}}}). In this form,
the ML extraction must be an ML inductive datatype, and the native
pattern matching of the language will be used.

\sphinxAtStartPar
When the initial \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}} matches the name of the type of characters or strings
(\sphinxcode{\sphinxupquote{char}} and \sphinxcode{\sphinxupquote{string}} for OCaml, \sphinxcode{\sphinxupquote{Prelude.Char}} and \sphinxcode{\sphinxupquote{Prelude.String}}
for Haskell), extraction of literals is handled in a specialized way, so as
to generate literals in the target language. This feature requires the type
designated by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} to be registered as the standard char or string type,
using the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Register}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Register}}}}} command.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{match}}$}}}}}}}}] \leavevmode
\sphinxAtStartPar
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 \(k\) constructors, the function used to
emulate the pattern matching should expect \(k+1\) arguments, first the \(k\)
branches in functional form, and then the inductive element to
destruct. For instance, the match branch \sphinxcode{\sphinxupquote{| S n => foo}} gives the
functional form \sphinxcode{\sphinxupquote{(fun n \sphinxhyphen{}> 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{| O => bar}} leads to the functional
form \sphinxcode{\sphinxupquote{(fun () \sphinxhyphen{}> bar)}}. For instance, when extracting \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}
into OCaml \sphinxcode{\sphinxupquote{int}}, the code to be provided has type:
\sphinxcode{\sphinxupquote{(unit\sphinxhyphen{}>'a)\sphinxhyphen{}>(int\sphinxhyphen{}>'a)\sphinxhyphen{}>int\sphinxhyphen{}>'a}}.

\end{description}

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{caution}{Caution:}
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
The ML code provided by the user is currently \sphinxstylestrong{not} checked at all by
extraction, even for syntax errors.

\item {} 
\sphinxAtStartPar
Extracting an inductive type to a pre\sphinxhyphen{}existing ML inductive type
is quite sound. But extracting to a general type (by providing an
ad\sphinxhyphen{}hoc pattern matching) will often \sphinxstylestrong{not} be fully rigorously
correct. For instance, when extracting \sphinxcode{\sphinxupquote{nat}} to OCaml \sphinxcode{\sphinxupquote{int}},
it is theoretically possible to build \sphinxcode{\sphinxupquote{nat}} values that are
larger than 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 {} 
\sphinxAtStartPar
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 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}

\sphinxAtStartPar
Typical examples are the following:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{n}{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{n}{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:}
\sphinxAtStartPar
When extracting to OCaml, if an inductive constructor or type has arity 2 and
the corresponding string is enclosed by parentheses, and the string meets
OCaml's lexical criteria for an infix symbol, then the rest of the string is
used as an infix constructor or type.
\end{sphinxadmonition}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{n}{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}

\sphinxAtStartPar
As an example of translation to a non\sphinxhyphen{}inductive datatype, let's turn
\sphinxcode{\sphinxupquote{nat}} into OCaml \sphinxcode{\sphinxupquote{int}} (see caveat above):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{n}{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}


\paragraph{Avoiding conflicts with existing filenames}
\label{\detokenize{addendum/extraction:avoiding-conflicts-with-existing-filenames}}
\sphinxAtStartPar
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 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 Coq and in OCaml.
It is possible to instruct the extraction not to use particular filenames.
\index{Extraction Blacklist (command)@\spxentry{Extraction Blacklist}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\sphinxAtStartPar
Instruct the extraction to avoid using these names as filenames
for extracted code.

\end{fulllineitems}\end{savenotes}

\index{Print Extraction Blacklist (command)@\spxentry{Print Extraction Blacklist}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Show the current list of filenames the extraction should avoid.

\end{fulllineitems}\end{savenotes}

\index{Reset Extraction Blacklist (command)@\spxentry{Reset Extraction Blacklist}\spxextra{command}}

\begin{savenotes}\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}}}}
\sphinxAtStartPar
Allow the extraction to use any filename.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
For OCaml, a typical use of these commands is
\sphinxcode{\sphinxupquote{Extraction Blacklist String List}}.


\paragraph{Additional settings}
\label{\detokenize{addendum/extraction:additional-settings}}\index{Extraction File Comment (option)@\spxentry{Extraction File Comment}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:opt.Extraction-File-Comment}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~File~Comment~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} provides a comment that is
included at the beginning of the output files.

\end{fulllineitems}\end{savenotes}

\index{Extraction Flag (option)@\spxentry{Extraction Flag}\spxextra{option}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:opt.Extraction-Flag}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Flag~{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-option}]{\sphinxtermref{\DUrole{xref,std,std-term}{option}}}} controls which optimizations are used during extraction, providing a finer\sphinxhyphen{}grained
control than {\hyperref[\detokenize{addendum/extraction:coq:flag.Extraction-Optimize}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Optimize}}}}}.  The bits of {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} are used as a bit mask.
Keeping an option off keeps the extracted ML more similar to the Coq term.
Values are:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline

\sphinxAtStartPar
Bit
&
\sphinxAtStartPar
Value
&
\sphinxAtStartPar
Optimization (default is on unless noted otherwise)
\\
\hline
\sphinxAtStartPar
0
&
\sphinxAtStartPar
1
&
\sphinxAtStartPar
Remove local dummy variables
\\
\hline
\sphinxAtStartPar
1
&
\sphinxAtStartPar
2
&
\sphinxAtStartPar
Use special treatment for fixpoints
\\
\hline
\sphinxAtStartPar
2
&
\sphinxAtStartPar
4
&
\sphinxAtStartPar
Simplify case with iota\sphinxhyphen{}redux
\\
\hline
\sphinxAtStartPar
3
&
\sphinxAtStartPar
8
&
\sphinxAtStartPar
Factor case branches as functions
\\
\hline
\sphinxAtStartPar
4
&
\sphinxAtStartPar
16
&
\sphinxAtStartPar
(not available, default false)
\\
\hline
\sphinxAtStartPar
5
&
\sphinxAtStartPar
32
&
\sphinxAtStartPar
Simplify case as function of one argument
\\
\hline
\sphinxAtStartPar
6
&
\sphinxAtStartPar
64
&
\sphinxAtStartPar
Simplify case by swapping case and lambda
\\
\hline
\sphinxAtStartPar
7
&
\sphinxAtStartPar
128
&
\sphinxAtStartPar
Some case optimization
\\
\hline
\sphinxAtStartPar
8
&
\sphinxAtStartPar
256
&
\sphinxAtStartPar
Push arguments inside a letin
\\
\hline
\sphinxAtStartPar
9
&
\sphinxAtStartPar
512
&
\sphinxAtStartPar
Use linear let reduction (default false)
\\
\hline
\sphinxAtStartPar
10
&
\sphinxAtStartPar
1024
&
\sphinxAtStartPar
Use linear beta reduction (default false)
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\end{fulllineitems}\end{savenotes}

\index{Extraction TypeExpand (flag)@\spxentry{Extraction TypeExpand}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.Extraction-TypeExpand}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~TypeExpand}}}}
\sphinxAtStartPar
If this {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}} is set, fully expand Coq types in ML.  See the Coq source code to learn more.

\end{fulllineitems}\end{savenotes}



\subsubsection{Differences between Coq and ML type systems}
\label{\detokenize{addendum/extraction:differences-between-coq-and-ml-type-systems}}
\sphinxAtStartPar
Due to differences between Coq and ML type systems,
some extracted programs are not directly typable in ML.
We now solve this problem (at least in OCaml) by adding
when needed some unsafe casting \sphinxcode{\sphinxupquote{Obj.magic}}, which give
a generic type \sphinxcode{\sphinxupquote{'a}} to any term.

\sphinxAtStartPar
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\sphinxhyphen{}pair}}
function:

\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}

\sphinxAtStartPar
In OCaml, for instance, the direct extracted term would be:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
let dp x y f = Pair((f () x),(f () y))
\end{sphinxVerbatim}

\sphinxAtStartPar
and would have type:

\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}

\sphinxAtStartPar
which is not its original type, but a restriction.

\sphinxAtStartPar
We now produce the following correct version:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
let dp x y f = Pair ((Obj.magic f () x), (Obj.magic f () y))
\end{sphinxVerbatim}

\sphinxAtStartPar
Secondly, some 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:

\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}

\sphinxAtStartPar
which corresponds to the definition of an ML dynamic type.
In OCaml, we must cast any argument of the constructor dummy
(no GADT are produced yet by the extraction).

\sphinxAtStartPar
Even with those unsafe castings, you should never get error like
\sphinxcode{\sphinxupquote{segmentation fault}}. In fact even if your program may seem
ill\sphinxhyphen{}typed to the OCaml type checker, it can't go wrong : it comes
from a Coq well\sphinxhyphen{}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 Coq point\sphinxhyphen{}of\sphinxhyphen{}view).

\sphinxAtStartPar
More details about the correctness of the extracted programs can be
found in {[}\hyperlink{cite.zebibliography:id32}{Let02}{]}.

\sphinxAtStartPar
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 OCaml
type checker without any \sphinxcode{\sphinxupquote{Obj.magic}} (see examples below).


\subsubsection{Some examples}
\label{\detokenize{addendum/extraction:some-examples}}
\sphinxAtStartPar
We present here two examples of extraction, taken from the
Coq Standard Library. We choose 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.


\paragraph{A detailed example: Euclidean division}
\label{\detokenize{addendum/extraction:a-detailed-example-euclidean-division}}
\sphinxAtStartPar
The file \sphinxcode{\sphinxupquote{Euclid}} contains the proof of Euclidean division.
The natural numbers used here are unary, represented by the type \sphinxcode{\sphinxupquote{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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall b:nat, b \PYGZgt{} 0 \PYGZhy{}\PYGZgt{} forall a:nat, diveucl a b
\end{sphinxVerbatim}

\sphinxAtStartPar
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 OCaml:

\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{n}{nat} \PYG{o}{=}
    \PYG{o}{|} \PYG{n}{O}
    \PYG{o}{|} \PYG{n}{S} \PYG{k}{of} \PYG{n}{nat}
    
    \PYG{n}{type} \PYG{n}{sumbool} \PYG{o}{=}
    \PYG{o}{|} \PYG{n}{Left}
    \PYG{o}{|} \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}{|} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n}
      \PYG{o}{|} \PYG{n}{S} \PYG{n}{k} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
                \PYG{o}{|} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n}
                \PYG{o}{|} \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}{|} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Left}
      \PYG{o}{|} \PYG{n}{S} \PYG{n}{n0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
                 \PYG{o}{|} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Right}
                 \PYG{o}{|} \PYG{n}{S} \PYG{n}{n1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{le\PYGZus{}lt\PYGZus{}dec} \PYG{n}{n0} \PYG{n}{n1}\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}{|} \PYG{n}{Divex} \PYG{k}{of} \PYG{n}{nat} \PYG{o}{*} \PYG{n}{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}{|} \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}{|} \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}

\sphinxAtStartPar
The inlining of \sphinxcode{\sphinxupquote{gt\_wf\_rec}} and others is not
mandatory. It only enhances readability of extracted code.
You can then copy\sphinxhyphen{}paste the output to a file \sphinxcode{\sphinxupquote{euclid.ml}} or let
Coq do it for you with the following command:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Extraction \PYGZdq{}euclid\PYGZdq{} eucl\PYGZus{}dev.
\end{sphinxVerbatim}

\sphinxAtStartPar
Let us play the resulting program (in an OCaml toplevel):

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZsh{}use \PYGZdq{}euclid.ml\PYGZdq{};;
type nat = O | S of nat
type sumbool = Left | 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}

\sphinxAtStartPar
It is easier to test on OCaml integers:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZsh{} let rec nat\PYGZus{}of\PYGZus{}int = function 0 \PYGZhy{}\PYGZgt{} O | 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 | 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}

\sphinxAtStartPar
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.


\paragraph{Extraction's horror museum}
\label{\detokenize{addendum/extraction:extraction-s-horror-museum}}
\sphinxAtStartPar
Some pathological examples of extraction are grouped in the file
\sphinxcode{\sphinxupquote{test\sphinxhyphen{}suite/success/extraction.v}} of the sources of Coq.


\paragraph{Users' Contributions}
\label{\detokenize{addendum/extraction:users-contributions}}
\sphinxAtStartPar
Several of the Coq Users' Contributions use extraction to produce
certified programs. In particular the following ones have an automatic
extraction test:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{additions}} : \sphinxurl{https://github.com/coq-contribs/additions}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{bdds}} : \sphinxurl{https://github.com/coq-contribs/bdds}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{canon\sphinxhyphen{}bdds}} : \sphinxurl{https://github.com/coq-contribs/canon-bdds}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{chinese}} : \sphinxurl{https://github.com/coq-contribs/chinese}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{continuations}} : \sphinxurl{https://github.com/coq-contribs/continuations}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{coq\sphinxhyphen{}in\sphinxhyphen{}coq}} : \sphinxurl{https://github.com/coq-contribs/coq-in-coq}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{exceptions}} : \sphinxurl{https://github.com/coq-contribs/exceptions}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{firing\sphinxhyphen{}squad}} : \sphinxurl{https://github.com/coq-contribs/firing-squad}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{founify}} : \sphinxurl{https://github.com/coq-contribs/founify}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{graphs}} : \sphinxurl{https://github.com/coq-contribs/graphs}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{higman\sphinxhyphen{}cf}} : \sphinxurl{https://github.com/coq-contribs/higman-cf}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{higman\sphinxhyphen{}nw}} : \sphinxurl{https://github.com/coq-contribs/higman-nw}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{hardware}} : \sphinxurl{https://github.com/coq-contribs/hardware}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{multiplier}} : \sphinxurl{https://github.com/coq-contribs/multiplier}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{search\sphinxhyphen{}trees}} : \sphinxurl{https://github.com/coq-contribs/search-trees}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{stalmarck}} : \sphinxurl{https://github.com/coq-contribs/stalmarck}

\end{itemize}

\sphinxAtStartPar
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 {[}\hyperlink{cite.zebibliography:id32}{Let02}{]}.


\subsection{Program derivation}
\label{\detokenize{addendum/miscellaneous-extensions:program-derivation}}\label{\detokenize{addendum/miscellaneous-extensions::doc}}
\sphinxAtStartPar
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 (command)@\spxentry{Derive}\spxextra{command}}

\begin{savenotes}\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/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~SuchThat~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~As~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} can appear in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}. This command opens a new proof
presenting the user with a goal for \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} in which the name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} is
bound to an existential variable \sphinxcode{\sphinxupquote{\DUrole{operator}{?}\DUrole{name}{x}}} (formally, there are other goals
standing for the existential variables but they are shelved, as
described in {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:tacn.shelve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{shelve}}}}}).

\sphinxAtStartPar
When the proof ends two {\hyperref[\detokenize{language/core/definitions:term-constant}]{\sphinxtermref{\DUrole{xref,std,std-term}{constants}}}} are defined:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The first one is named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} and is defined as the proof of the
shelved goal (which is also the value of \sphinxcode{\sphinxupquote{\DUrole{operator}{?}\DUrole{name}{x}}}). It is always
transparent.

\item {} 
\sphinxAtStartPar
The second one is named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}. It has type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}, and its {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} is
the proof of the initially visible goal. It is opaque if the proof
ends with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}, and transparent if the proof ends with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}.

\end{itemize}

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example}

\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{n}{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}{goal}
    \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{n}{nat}
      \PYG{n}{p} \PYG{o}{:=} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{:} \PYG{n}{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}{goal}
    \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{n}{nat}
      \PYG{n}{p} \PYG{o}{:=} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{:} \PYG{n}{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}{goal}
    \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{n}{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}{goals}\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{n}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{k} \PYG{o}{*} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)}
         \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    
    \PYG{k+kn}{Arguments} \PYG{n}{p} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{nat\PYGZus{}scope}

\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{n}{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}

\sphinxAtStartPar
Any property can be used as \sphinxcode{\sphinxupquote{term}}, not only an equation. In particular,
it could be an order relation specifying some form of program
refinement or a non\sphinxhyphen{}executable property from which deriving a program
is convenient.


\subsection{Functional induction}
\label{\detokenize{using/libraries/funind:functional-induction}}\label{\detokenize{using/libraries/funind::doc}}

\subsubsection{Advanced recursive functions}
\label{\detokenize{using/libraries/funind:advanced-recursive-functions}}\label{\detokenize{using/libraries/funind:id1}}
\sphinxAtStartPar
The following command is available when the \sphinxcode{\sphinxupquote{FunInd}} library has been loaded via \sphinxcode{\sphinxupquote{Require Import FunInd}}:
\index{Function (command)@\spxentry{Function}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:cmd.Function}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Function~{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_definition}]{\sphinxcrossref{\DUrole{hole}{fix\_definition}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/core/inductive:grammar-token-fix_definition}]{\sphinxcrossref{\DUrole{hole}{fix\_definition}}}}}\DUrole{notation-sup}{*}}}}}}
\sphinxAtStartPar
This command is a generalization of {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}. It is 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{using/libraries/funind:coq:tacn.functional-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional induction}}}}}) and its fixpoint equality.
This defines a function similar to those defined by {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}.
As in {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}, the decreasing argument must
be given (unless the function is not recursive), but it might not
necessarily be \sphinxstyleemphasis{structurally} decreasing. Use the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}}} clause
to name the decreasing argument \sphinxstyleemphasis{and} to describe which kind of
decreasing criteria to use to ensure termination of recursive
calls.

\sphinxAtStartPar
{\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} also supports the \sphinxcode{\sphinxupquote{\DUrole{notation}{with}}} clause to create
mutually recursive definitions, however this feature is limited
to structurally recursive functions (i.e. when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}}} is a \sphinxcode{\sphinxupquote{\DUrole{notation}{struct}}}
clause).

\sphinxAtStartPar
See {\hyperref[\detokenize{using/libraries/funind:coq:tacn.functional-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional induction}}}}} and {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Functional-Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Functional Scheme}}}}} for how to use
the induction principle to reason easily about the function.

\sphinxAtStartPar
The form of the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}}} clause determines which definition mechanism {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} uses.
(Note that references to \sphinxcode{\sphinxupquote{\DUrole{notation}{ident}}} below refer to the name of the function being defined.):
\begin{itemize}
\item {} 
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/inductive:grammar-token-fixannot}]{\sphinxcrossref{\DUrole{hole}{fixannot}}}}}}} is not specified, {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}
defines the nonrecursive function {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} as if it was declared with
{\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}. In addition, the following are defined:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_rect}}, {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_rec}} and {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_ind}},
which reflect the pattern matching structure of {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} (see {\hyperref[\detokenize{language/core/inductive:coq:cmd.Inductive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Inductive}}}}});

\item {} 
\sphinxAtStartPar
The inductive \sphinxcode{\sphinxupquote{\DUrole{notation}{R\_{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} corresponding to the graph of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} (silently);

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_complete}} and {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_correct}} which
are inversion information linking the function and its graph.

\end{itemize}

\item {} 
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ struct ... \}}}}} is specified, {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}
defines the structural recursive function {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} as if it was declared
with {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}. In addition, the following are defined:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The same objects as above;

\item {} 
\sphinxAtStartPar
The fixpoint equation of {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}: \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_equation}}.

\end{itemize}

\item {} 
\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ measure ... \}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{ wf ... \}}}}} are specified, {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}
defines a recursive function by well\sphinxhyphen{}founded recursion. The module \sphinxcode{\sphinxupquote{Recdef}}
of the standard library must be loaded for this feature.
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{measure {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{1}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{2}}$}}}}}\DUrole{notation-sup}{?}} \}}}}}: where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the decreasing argument
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{1}}$}}}}}}} is a function from the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} to \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}} for which
the decreasing argument decreases (for the \sphinxcode{\sphinxupquote{\DUrole{name}{lt}}} order on \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}})
for each recursive call of the function. The parameters of the function are
bound in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term$_{\text{1}}$}}}}}}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{wf {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \}}}}}: where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the decreasing argument and
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}} is an ordering relation on the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} (i.e. of type
\sphinxcode{\sphinxupquote{T}}\(_{\sf ident}\) → \sphinxcode{\sphinxupquote{T}}\(_{\sf ident}\) → \sphinxcode{\sphinxupquote{Prop}}) for which the decreasing argument
decreases for each recursive call of the function. The order must be well\sphinxhyphen{}founded.
The parameters of the function are bound in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}.

\end{itemize}

\sphinxAtStartPar
If the clause is \sphinxcode{\sphinxupquote{measure}} or \sphinxcode{\sphinxupquote{wf}}, 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 \sphinxcode{\sphinxupquote{wf}}) a proof
that the ordering relation is well\sphinxhyphen{}founded. Once proof obligations are
discharged, the following objects are defined:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The same objects as with the \sphinxcode{\sphinxupquote{struct}} clause;

\item {} 
\sphinxAtStartPar
The lemma \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_tcc}} which collects all proof obligations in one
property;

\item {} 
\sphinxAtStartPar
The lemmas \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_terminate}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}\sphinxcode{\sphinxupquote{\_F}} which will be inlined
during extraction of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{itemize}

\sphinxAtStartPar
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.

\end{itemize}

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Function} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
\PYG{o}{|} \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}{guarded} \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{}rect} \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}{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}

\sphinxAtStartPar
than like this:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Function} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{|} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
\PYG{o}{|} \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}{guarded} \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{}rect} \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}{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}
\end{sphinxadmonition}

\sphinxAtStartPar
\sphinxstyleemphasis{Limitations}

\sphinxAtStartPar
{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} must be built as a \sphinxstyleemphasis{pure pattern matching tree} (\sphinxcode{\sphinxupquote{\DUrole{keyword}{match} \DUrole{name,builtin,pseudo}{…} \DUrole{keyword}{with}}})
with applications only \sphinxstyleemphasis{at the end} of each branch.

\sphinxAtStartPar
{\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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 \sphinxcode{\sphinxupquote{\DUrole{name}{wrong}}} in the body of \sphinxcode{\sphinxupquote{\DUrole{name}{wrong}}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Function} \PYG{n}{wrong} \PYG{o}{(}\PYG{n}{C}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{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}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{70}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{Function} \PYG{n}{wrong} \PYG{o}{(}\PYG{n}{C}\PYG{o}{:}\PYG{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{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{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{n}{Error}\PYG{o}{:}
    \PYG{n}{Recursive} \PYG{n}{definition} \PYG{k}{of} \PYG{n}{wrong} \PYG{k}{is} \PYG{n}{ill}\PYG{o}{\PYGZhy{}}\PYG{n}{formed}\PYG{o}{.}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{wrong} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat}
    \PYG{n}{C} \PYG{o}{:} \PYG{n}{nat}
    \PYG{n}{Recursive} \PYG{n}{call} \PYG{n}{to} \PYG{n}{wrong} \PYG{n}{has} \PYG{n}{principal} \PYG{n}{argument} \PYG{n}{equal} \PYG{n}{to} 
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{C}\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}{C}\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 C : nat =\PYGZgt{} List.hd 0 (List.map wrong [C])}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

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

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind: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}\end{savenotes}

\index{No argument name ‘ident’ (error)@\spxentry{No argument name ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:exn.No-argument-name-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~argument~name~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{Cannot use mutual definition with well\sphinxhyphen{}founded recursion or measure (error)@\spxentry{Cannot use mutual definition with well\sphinxhyphen{}founded recursion or measure}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind: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\sphinxhyphen{}founded~recursion~or~measure.}}}}
\end{fulllineitems}\end{savenotes}

\index{Cannot define graph for ‘ident’ (warning)@\spxentry{Cannot define graph for ‘ident’}\spxextra{warning}}

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

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

\end{itemize}

\end{fulllineitems}\end{savenotes}

\index{Cannot define principle(s) for ‘ident’ (warning)@\spxentry{Cannot define principle(s) for ‘ident’}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:warn.Cannot-define-principle(s)-for-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~define~principle(s)~for~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\sphinxAtStartPar
The generation of the graph relation (\sphinxcode{\sphinxupquote{\DUrole{notation}{R\_{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}) succeeded but the induction principle
could not be built. Only {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is defined. Please report.

\end{fulllineitems}\end{savenotes}

\index{Cannot build functional inversion principle (warning)@\spxentry{Cannot build functional inversion principle}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:warn.Cannot-build-functional-inversion-principle}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~build~functional~inversion~principle.}}}}
\sphinxAtStartPar
{\hyperref[\detokenize{using/libraries/funind:coq:tacn.functional-inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional inversion}}}}} will not be available for the function.

\end{fulllineitems}\end{savenotes}



\subsubsection{Tactics}
\label{\detokenize{using/libraries/funind:tactics}}\index{functional induction (tactic)@\spxentry{functional induction}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:tacn.functional-induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{functional~induction~{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Performs case analysis and induction following the definition of a function
{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}, which must be fully applied to its arguments as part of
{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. It uses a principle
generated by {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} or {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Functional-Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Functional Scheme}}}}}.
Note that this tactic is only available after a \sphinxcode{\sphinxupquote{Require Import FunInd}}.
See the {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} command.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{using {\hyperref[\detokenize{language/core/basic:grammar-token-one_term}]{\sphinxcrossref{\DUrole{hole}{one\_term}}}}}}}}] \leavevmode
\sphinxAtStartPar
Specifies the induction principle (aka elimination scheme).

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings}]{\sphinxcrossref{\DUrole{hole}{bindings}}}}}}}}] \leavevmode
\sphinxAtStartPar
Specifies the arguments of the induction principle.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{as {\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}}}}] \leavevmode
\sphinxAtStartPar
Provides names for the introduced variables.

\end{description}

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{FunInd}\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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{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{n}{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{n}{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{n}{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{n}{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{n}{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{n}{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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
\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/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} followed by a cleaning
phase, where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is the induction principle registered for \sphinxcode{\sphinxupquote{\DUrole{name}{f}}}
(by the {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} or {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Functional-Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Functional Scheme}}}}} command)
corresponding to the sort of the goal. Therefore
{\hyperref[\detokenize{using/libraries/funind:coq:tacn.functional-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional induction}}}}} may fail if the induction scheme \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is not
defined.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
There is a difference between obtaining an induction scheme
for a function by using {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}
and by using {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Functional-Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Functional Scheme}}}}} after a normal definition using
{\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} or {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}.
\end{sphinxadmonition}
\index{Cannot find induction information on ‘qualid’ (error)@\spxentry{Cannot find induction information on ‘qualid’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:exn.Cannot-find-induction-information-on-_u2018qualid_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~induction~information~on~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}\end{savenotes}

\index{Not the right number of induction arguments (error)@\spxentry{Not the right number of induction arguments}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind: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}\end{savenotes}


\end{fulllineitems}\end{savenotes}

\index{functional inversion (tactic)@\spxentry{functional inversion}\spxextra{tactic}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:tacn.functional-inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Tactic}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{functional~inversion~\DUrole{alternative}{\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{?}}}}}}
\sphinxAtStartPar
Performs inversion on hypothesis
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}} = {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} or
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is defined using {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}.
Note that this tactic is only available after a \sphinxcode{\sphinxupquote{Require Import FunInd}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}}}] \leavevmode
\sphinxAtStartPar
Does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural}}}}}}} followed by
\sphinxcode{\sphinxupquote{\DUrole{notation}{functional inversion {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the
identifier for the last introduced hypothesis.

\item[{\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}] \leavevmode
\sphinxAtStartPar
If the hypothesis {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} (or {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}) has a type of the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{1}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{i}}$}}}}}\DUrole{notation-sup}{+}} = {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{j}}$}}}}}\DUrole{notation-sup}{+}}}}} where
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid$_{\text{2}}$}}}}}}} are valid candidates to
functional inversion, this variant allows choosing which {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}
is inverted.

\end{description}
\index{Hypothesis ‘ident’ must contain at least one Function (error)@\spxentry{Hypothesis ‘ident’ must contain at least one Function}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:exn.Hypothesis-_u2018ident_u2019-must-contain-at-least-one-Function}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hypothesis~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~must~contain~at~least~one~Function.}}}}
\end{fulllineitems}\end{savenotes}

\index{Cannot find inversion information for hypothesis ‘ident’ (error)@\spxentry{Cannot find inversion information for hypothesis ‘ident’}\spxextra{error}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:exn.Cannot-find-inversion-information-for-hypothesis-_u2018ident_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~inversion~information~for~hypothesis~{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\sphinxAtStartPar
This error may be raised when some inversion lemma failed to be generated by
Function.

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}



\subsubsection{Generation of induction principles with \sphinxstyleliteralintitle{\sphinxupquote{Functional}} \sphinxstyleliteralintitle{\sphinxupquote{Scheme}}}
\label{\detokenize{using/libraries/funind:generation-of-induction-principles-with-functional-scheme}}\label{\detokenize{using/libraries/funind:functional-scheme}}\index{Functional Scheme (command)@\spxentry{Functional Scheme}\spxextra{command}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/funind:coq:cmd.Functional-Scheme}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Functional~Scheme~{\hyperref[\detokenize{using/libraries/funind:grammar-token-func_scheme_def}]{\sphinxcrossref{\DUrole{hole}{func\_scheme\_def}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{using/libraries/funind:grammar-token-func_scheme_def}]{\sphinxcrossref{\DUrole{hole}{func\_scheme\_def}}}}}\DUrole{notation-sup}{*}}}}}}~\DUrole{prodn-table}{\DUrole{prodn-column-group}{\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}\DUrole{prodn-column}{}}\DUrole{prodn-row-group}{\DUrole{prodn-row}{\DUrole{prodn-cell-nonterminal}{\DUrole{prodn-target}{\phantomsection\label{\detokenize{using/libraries/funind:grammar-token-func_scheme_def}}}\DUrole{notation}{{\hyperref[\detokenize{using/libraries/funind:grammar-token-func_scheme_def}]{\sphinxcrossref{\DUrole{hole}{func\_scheme\_def}}}}}}\DUrole{prodn-cell-op}{\sphinxcode{\sphinxupquote{::=}}}\DUrole{prodn-cell-production}{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := Induction for {\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} Sort {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:grammar-token-sort_family}]{\sphinxcrossref{\DUrole{hole}{sort\_family}}}}}}\DUrole{prodn-cell-tag}{\sphinxcode{\sphinxupquote{}}}}}}
\sphinxAtStartPar
An experimental high\sphinxhyphen{}level tool that
automatically generates induction principles corresponding to functions that
may be mutually recursive.  The command generates an
induction principle named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} for each given function named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}s must be given in the same order as when they were defined.

\sphinxAtStartPar
Note the command must be made available via {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}} \sphinxcode{\sphinxupquote{FunInd}}.

\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
There is a difference between induction schemes generated by the command
{\hyperref[\detokenize{using/libraries/funind:coq:cmd.Functional-Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Functional Scheme}}}}} and these generated by the {\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}. Indeed,
{\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} generally produces smaller principles that are closer to how
a user would implement them. See {\hyperref[\detokenize{using/libraries/funind:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}} for details.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Induction scheme for div2.

\sphinxAtStartPar
We define the function div2 as follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{FunInd}\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}{ring\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{n}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
\PYG{o}{|} \PYG{n}{S} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
\PYG{o}{|} \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}{guarded} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
The definition of a principle of induction corresponding to the
recursive structure of \sphinxcode{\sphinxupquote{div2}} is defined by the command:

\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}

\sphinxAtStartPar
You may now look at the type of div2\_ind:

\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{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{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{n}{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{n}{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{n}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
We can now prove the following lemma using this principle:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{div2\PYGZus{}le\PYGZsq{}} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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{n}{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}{goals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{n0} \PYG{o}{:} \PYG{n}{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}{goal} \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}{goal} \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}{goals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{n0}\PYG{o}{,} \PYG{n}{n1} \PYG{o}{:} \PYG{n}{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}{goal} \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}{goal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{n0}\PYG{o}{,} \PYG{n}{n1} \PYG{o}{:} \PYG{n}{nat}
      \PYG{n}{e} \PYG{o}{:} \PYG{n}{n0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n1}
      \PYG{n}{n\PYGZsq{}} \PYG{o}{:} \PYG{n}{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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
We can use directly the functional induction ({\hyperref[\detokenize{using/libraries/funind:coq:tacn.functional-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional induction}}}}}) tactic instead
of the pattern/apply trick:

\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{n}{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}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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{n}{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}{goal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{n}{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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \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}{goal} \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}{goals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{goal} \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}{goal}
      
      \PYG{n}{n\PYGZsq{}} \PYG{o}{:} \PYG{n}{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}{goals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Induction scheme for tree\_size.

\sphinxAtStartPar
We define trees by the following mutual inductive type:

\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}{|} \PYG{n}{empty} \PYG{o}{:} \PYG{n}{forest}
\PYG{o}{|} \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}{tree\PYGZus{}sind} \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}{forest\PYGZus{}sind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxAtStartPar
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.

\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{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{t} \PYG{k}{with}
\PYG{o}{|} \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{n}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
\PYG{o}{|} \PYG{n}{empty} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
\PYG{o}{|} \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}{guarded} \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{}rect} \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}{forest\PYGZus{}size\PYGZus{}equation} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}size\PYGZus{}rect} \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}{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}

\sphinxAtStartPar
Notice that the induction principles \sphinxcode{\sphinxupquote{tree\_size\_ind}} and \sphinxcode{\sphinxupquote{forest\_size\_ind}}
generated by \sphinxcode{\sphinxupquote{Function}} are not mutual.

\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{n}{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}

\sphinxAtStartPar
Mutual induction principles following the recursive structure of \sphinxcode{\sphinxupquote{tree\_size}}
and \sphinxcode{\sphinxupquote{forest\_size}} can be generated by the following command:

\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}

\sphinxAtStartPar
You may now look at the type of \sphinxcode{\sphinxupquote{tree\_size\_ind2}}:

\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{n}{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{n}{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{Writing Coq libraries and plugins}
\label{\detokenize{using/libraries/writing:writing-coq-libraries-and-plugins}}\label{\detokenize{using/libraries/writing::doc}}
\sphinxAtStartPar
This section presents the part of the Coq language that is useful only
to library and plugin authors.  A tutorial for writing Coq plugins is
available in the Coq repository in \sphinxhref{https://github.com/coq/coq/tree/master/doc/plugin\_tutorial}{doc/plugin\_tutorial}%
\begin{footnote}[57]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/tree/master/doc/plugin\_tutorial}
%
\end{footnote}.


\subsubsection{Deprecating library objects or tactics}
\label{\detokenize{using/libraries/writing:deprecating-library-objects-or-tactics}}
\sphinxAtStartPar
You may use the following {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attribute}}}} to deprecate a notation or
tactic.  When renaming a definition or theorem, you can introduce a
deprecated compatibility alias using {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation-(abbreviation)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation (abbreviation)}}}}}
(see {\hyperref[\detokenize{using/libraries/writing:compatibility-alias}]{\sphinxcrossref{\DUrole{std,std-ref}{the example below}}}}).
\index{deprecated (attribute)@\spxentry{deprecated}\spxextra{attribute}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/writing:coq:attr.deprecated}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Attribute}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{deprecated~(~\DUrole{repeat-wrapper}{\DUrole{repeat}{since~=~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~,}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{note~=~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}}~)}}}}
\sphinxAtStartPar
At least one of \sphinxcode{\sphinxupquote{\DUrole{notation}{since}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{note}}} must be present.  If both
are present, either one may appear first and they must be separated
by a comma.

\sphinxAtStartPar
This attribute is supported by the following commands: {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Ltac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac}}}}},
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Tactic-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Tactic Notation}}}}}, {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}}, {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Infix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Infix}}}}}, {\hyperref[\detokenize{proof-engine/ltac2:coq:cmd.Ltac2}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac2}}}}},
{\hyperref[\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac2 Notation}}}}}, {\hyperref[\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-external}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac2 external}}}}}.

\sphinxAtStartPar
It can trigger the following warnings:
\index{Tactic ‘qualid’ is deprecated since ‘string’. ‘string’ (warning)@\spxentry{Tactic ‘qualid’ is deprecated since ‘string’. ‘string’}\spxextra{warning}}\index{Tactic Notation ‘qualid’ is deprecated since ‘string’. ‘string’ (warning)@\spxentry{Tactic Notation ‘qualid’ is deprecated since ‘string’. ‘string’}\spxextra{warning}}\index{Notation ‘string’ is deprecated since ‘string’. ‘string’ (warning)@\spxentry{Notation ‘string’ is deprecated since ‘string’. ‘string’}\spxextra{warning}}\index{Ltac2 definition ‘qualid’ is deprecated since ‘string’. ‘string’ (warning)@\spxentry{Ltac2 definition ‘qualid’ is deprecated since ‘string’. ‘string’}\spxextra{warning}}\index{Ltac2 alias ‘qualid’ is deprecated since ‘string’. ‘string’ (warning)@\spxentry{Ltac2 alias ‘qualid’ is deprecated since ‘string’. ‘string’}\spxextra{warning}}\index{Ltac2 notation ‘ltac2\_scope’…‘ltac2\_scope’ is deprecated since ‘string’. ‘string’ (warning)@\spxentry{Ltac2 notation ‘ltac2\_scope’…‘ltac2\_scope’ is deprecated since ‘string’. ‘string’}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{using/libraries/writing:coq:warn.Tactic-_u2018qualid_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~deprecated~since~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{since}}$}}}}.~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{note}}$}}}}.}}}}\phantomsection\label{\detokenize{using/libraries/writing:coq:warn.Tactic-Notation-_u2018qualid_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~Notation~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~deprecated~since~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{since}}$}}}}.~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{note}}$}}}}.}}}}\phantomsection\label{\detokenize{using/libraries/writing:coq:warn.Notation-_u2018string_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Notation~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~is~deprecated~since~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{since}}$}}}}.~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{note}}$}}}}.}}}}\phantomsection\label{\detokenize{using/libraries/writing:coq:warn.Ltac2-definition-_u2018qualid_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~definition~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~deprecated~since~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{since}}$}}}}.~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{note}}$}}}}.}}}}\phantomsection\label{\detokenize{using/libraries/writing:coq:warn.Ltac2-alias-_u2018qualid_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~alias~{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~deprecated~since~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{since}}$}}}}.~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{note}}$}}}}.}}}}\phantomsection\label{\detokenize{using/libraries/writing:coq:warn.Ltac2-notation-_u2018ltac2_scope_u2019_u2026_u2018ltac2_scope_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac2~notation~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac2:grammar-token-ltac2_scope}]{\sphinxcrossref{\DUrole{hole}{ltac2\_scope}}}}}\DUrole{notation-sup}{+}}~is~deprecated~since~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{since}}$}}}}.~{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{note}}$}}}}.}}}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} is the notation,
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{since}}$}}}}}}} is the version number, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string$_{\text{note}}$}}}}}}} is
the note (usually explains the replacement).

\end{fulllineitems}\end{savenotes}


\end{fulllineitems}\end{savenotes}


\begin{sphinxadmonition}{note}{Example: Deprecating a tactic.}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{\PYGZsh{}}\PYG{o}{[}\PYG{n}{deprecated}\PYG{o}{(}\PYG{n}{since}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{0.9}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{,} \PYG{n}{note}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Use idtac instead.}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{]}
\PYG{k+kn}{Ltac} \PYG{n}{foo} \PYG{o}{:=} \PYG{k+kr}{idtac}\PYG{o}{.}
    \PYG{n}{foo} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{goal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{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}{now} \PYG{n}{foo}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{4}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{7}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{now} \PYG{n}{foo}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}     \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{k+kn}{Tactic} \PYG{n}{foo} \PYG{k}{is} \PYG{n}{deprecated} \PYG{n}{since} \PYG{l+m+mi}{0}\PYG{o}{.}\PYG{l+m+mi}{9}\PYG{o}{.} \PYG{n}{Use} \PYG{k+kr}{idtac} \PYG{n}{instead}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{deprecated}\PYG{o}{\PYGZhy{}}\PYG{n}{tactic}\PYG{o}{,}\PYG{n}{deprecated}\PYG{o}{]}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{goals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{using/libraries/writing:compatibility-alias}}
\begin{sphinxadmonition}{note}{Example: Introducing a compatibility alias}

\sphinxAtStartPar
Let's say your library initially contained:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{foo} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{x}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
and you want to rename \sphinxcode{\sphinxupquote{foo}} into \sphinxcode{\sphinxupquote{bar}}, but you want to avoid breaking
your users' code without advanced notice.  To do so, replace the previous
code by the following:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{bar} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{x}\PYG{o}{.}
\PYG{o}{\PYGZsh{}}\PYG{o}{[}\PYG{n}{deprecated}\PYG{o}{(}\PYG{n}{since}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1.2}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{,} \PYG{n}{note}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Use bar instead.}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{]}
\PYG{k+kn}{Notation} \PYG{n}{foo} \PYG{o}{:=} \PYG{n}{bar} \PYG{o}{(}\PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
Then, the following code still works, but emits a warning:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{foo} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{7}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{10}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{foo} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}        \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{k+kn}{Notation} \PYG{n}{foo} \PYG{k}{is} \PYG{n}{deprecated} \PYG{n}{since} \PYG{l+m+mi}{1}\PYG{o}{.}\PYG{l+m+mi}{2}\PYG{o}{.} \PYG{n}{Use} \PYG{n}{bar} \PYG{n}{instead}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{deprecated}\PYG{o}{\PYGZhy{}}\PYG{n}{syntactic}\PYG{o}{\PYGZhy{}}\PYG{n}{definition}\PYG{o}{,}\PYG{n}{deprecated}\PYG{o}{]}
    \PYG{n}{bar} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{n}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\section{Command\sphinxhyphen{}line and graphical tools}
\label{\detokenize{using/tools/index:command-line-and-graphical-tools}}\label{\detokenize{using/tools/index:tools}}\label{\detokenize{using/tools/index::doc}}
\sphinxAtStartPar
This chapter presents the command\sphinxhyphen{}line tools that users will need to
build their Coq project, the documentation of the CoqIDE standalone
user interface and the documentation of the parallel proof processing
feature that is supported by CoqIDE and several other user interfaces.
A list of available user interfaces to interact with Coq is available
on the \sphinxhref{https://coq.inria.fr/user-interfaces.html}{Coq website}%
\begin{footnote}[58]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.inria.fr/user-interfaces.html}
%
\end{footnote}.


\subsection{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}}
\sphinxAtStartPar
There are three Coq commands:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{coqtop}}: the Coq toplevel (interactive mode);

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{coqc}}: the Coq compiler (batch compilation);

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{coqchk}}: the Coq checker (validation of compiled libraries).

\end{itemize}

\sphinxAtStartPar
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.


\subsubsection{Interactive use (coqtop)}
\label{\detokenize{practical-tools/coq-commands:interactive-use-coqtop}}\label{\detokenize{practical-tools/coq-commands:interactive-use}}
\sphinxAtStartPar
In the interactive mode, also known as the Coq toplevel, the user can
develop his theories and proofs step by step. The Coq toplevel is run
by the command \sphinxcode{\sphinxupquote{coqtop}}.

\sphinxAtStartPar
There are two different binary images of Coq: the byte\sphinxhyphen{}code one and the
native\sphinxhyphen{}code one (if OCaml provides a native\sphinxhyphen{}code compiler for
your platform, which is supposed in the following). By default,
\sphinxcode{\sphinxupquote{coqtop}} executes the native\sphinxhyphen{}code version; run \sphinxcode{\sphinxupquote{coqtop.byte}} to get
the byte\sphinxhyphen{}code version.

\sphinxAtStartPar
The byte\sphinxhyphen{}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 Coq
toplevel with the command \sphinxcode{\sphinxupquote{Coqloop.loop();;}}.
\index{Coqtop Exit On Error (flag)@\spxentry{Coqtop Exit On Error}\spxextra{flag}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{practical-tools/coq-commands:coq:flag.Coqtop-Exit-On-Error}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Coqtop~Exit~On~Error}}}}
\sphinxAtStartPar
This {\hyperref[\detokenize{language/core/basic:term-flag}]{\sphinxtermref{\DUrole{xref,std,std-term}{flag}}}}, off by default, causes coqtop to exit with status code
\sphinxcode{\sphinxupquote{1}} if a command produces an error instead of recovering from it.

\end{fulllineitems}\end{savenotes}



\subsubsection{Batch compilation (coqc)}
\label{\detokenize{practical-tools/coq-commands:batch-compilation-coqc}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{coqc}} command compiles a Coq proof script file with a ".v" suffix
to create a compiled file with a ".vo" suffix.  (See {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}}.)
The last component of the filename must be a valid Coq identifier as described in
{\hyperref[\detokenize{language/core/basic:lexical-conventions}]{\sphinxcrossref{\DUrole{std,std-ref}{Lexical conventions}}}}; it should contain only letters, digits or
underscores (\_) with a ".v" suffix on the final component.
For example \sphinxcode{\sphinxupquote{/bar/foo/toto.v}} is valid, but \sphinxcode{\sphinxupquote{/bar/foo/to\sphinxhyphen{}to.v}} is not.

\sphinxAtStartPar
We recommend specifying a logical directory name (which is also the module name)
with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}} or the \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}} options.
Generally we recommend using utilities such as \sphinxcode{\sphinxupquote{make}} (using \sphinxcode{\sphinxupquote{coq\_makefile}}
to generate the \sphinxcode{\sphinxupquote{Makefile}}) or \sphinxcode{\sphinxupquote{dune}} to build Coq projects.
See {\hyperref[\detokenize{practical-tools/utilities:building-coq-project}]{\sphinxcrossref{\DUrole{std,std-ref}{Building a Coq project}}}}.

\begin{sphinxadmonition}{note}{Example: Compiling and loading a single file}

\sphinxAtStartPar
If \sphinxcode{\sphinxupquote{foo.v}} is in Coq's current directory, you can use \sphinxcode{\sphinxupquote{coqc foo.v}}
to compile it and then \sphinxcode{\sphinxupquote{Require foo.}} in your script.  But this
doesn't scale well for larger projects.

\sphinxAtStartPar
Generally it's' better to define a new module:
To compile \sphinxcode{\sphinxupquote{foo.v}} as part of a module \sphinxcode{\sphinxupquote{Mod1}} that is rooted
at \sphinxcode{\sphinxupquote{.}} (i.e. the directory containing \sphinxcode{\sphinxupquote{foo.v}}), run \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}Q . Mod1 foo.v}}.

\sphinxAtStartPar
To make the module available in \sphinxcode{\sphinxupquote{CoqIDE}}, include the following line in the
\sphinxcode{\sphinxupquote{\_CoqProject}} file (see {\hyperref[\detokenize{practical-tools/utilities:coq-makefile}]{\sphinxcrossref{\DUrole{std,std-ref}{Building a Coq project with coq\_makefile}}}}) in the directory from which you
start \sphinxcode{\sphinxupquote{CoqIDE}}.  \sphinxstyleemphasis{<PATH>} is the pathname of the directory containing the module,
which can be an absolute path or relative to Coq's current directory.  For now,
you must close and reload a named script file for \sphinxcode{\sphinxupquote{CoqIDE}} to pick up the change,
or restart \sphinxcode{\sphinxupquote{CoqIDE}}.
The project file name is configurable in \sphinxcode{\sphinxupquote{Edit / Preferences / Project}}.
\begin{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{\PYGZhy{}}\PYG{n}{R} \PYG{o}{\PYGZlt{}}\PYG{n}{PATH}\PYG{o}{\PYGZgt{}} \PYG{n}{Mod1}
\end{sphinxVerbatim}
\end{quote}

\sphinxAtStartPar
It's also possible to load a module within \sphinxcode{\sphinxupquote{coqtop}} or \sphinxcode{\sphinxupquote{coqide}} with
commands like these.  The drawback of this is that it adds
environment\sphinxhyphen{}specific information (the PATH) to your script, making
it non\sphinxhyphen{}portable, so we discourage using this approach.
\begin{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Add} \PYG{n}{LoadPath} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{PATH}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{as} \PYG{n}{Mod1}\PYG{o}{.}
\PYG{k+kn}{Require} \PYG{n}{Mod1}\PYG{o}{.}\PYG{n}{foo}\PYG{o}{.}
\end{sphinxVerbatim}
\end{quote}

\sphinxAtStartPar
in which \sphinxcode{\sphinxupquote{PATH}} is the pathname of the directory containing \sphinxcode{\sphinxupquote{foo.v}}, which
can be absolute or relative to Coq's current directory.  The
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Add-LoadPath}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add LoadPath}}}}} is not needed if you provide the mapping from the
logical directory (module name) to the physical directory by including the
\sphinxcode{\sphinxupquote{\sphinxhyphen{}Q . Mod1}} as command\sphinxhyphen{}line arguments to \sphinxcode{\sphinxupquote{coqtop}} or \sphinxcode{\sphinxupquote{coqide}}.
\end{sphinxadmonition}


\subsubsection{Customization at launch time}
\label{\detokenize{practical-tools/coq-commands:customization-at-launch-time}}

\paragraph{By resource file}
\label{\detokenize{practical-tools/coq-commands:by-resource-file}}
\sphinxAtStartPar
When 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{\sphinxhyphen{}init\sphinxhyphen{}file}} below).

\sphinxAtStartPar
The resource file may contain, for instance, \sphinxcode{\sphinxupquote{Add LoadPath}} commands to add
directories to the load path of Coq. It is possible to skip the
loading of the resource file with the option \sphinxcode{\sphinxupquote{\sphinxhyphen{}q}}.


\paragraph{By environment variables}
\label{\detokenize{practical-tools/coq-commands:by-environment-variables}}\label{\detokenize{practical-tools/coq-commands:customization-by-environment-variables}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\$COQPATH}} can be used to specify the load path. It is a list of directories separated by
\sphinxcode{\sphinxupquote{:}} (\sphinxcode{\sphinxupquote{;}} on Windows). Coq will also honor \sphinxcode{\sphinxupquote{\$XDG\_DATA\_HOME}} and
\sphinxcode{\sphinxupquote{\$XDG\_DATA\_DIRS}} (see Section {\hyperref[\detokenize{language/core/modules:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}).

\sphinxAtStartPar
Some Coq commands call other 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.

\phantomsection\label{\detokenize{practical-tools/coq-commands:coq-colors}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\$COQ\_COLORS}} 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\sphinxhyphen{}separated
list of assignments of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{name=\DUrole{repeat-wrapper-with-sub}{\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{\sphinxhyphen{}list\sphinxhyphen{}tags}} command\sphinxhyphen{}line option of \sphinxcode{\sphinxupquote{coqtop}}.

\sphinxAtStartPar
The string uses ANSI escape codes to represent attributes.  For example:
\begin{quote}

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{export COQ\_COLORS=”diff.added=4;48;2;0;0;240:diff.removed=41”}}
\end{quote}

\sphinxAtStartPar
sets the highlights for added text in diffs to underlined (the 4) with a background RGB
color (0, 0, 240) and for removed text in diffs to a red background.
Note that if you specify \sphinxcode{\sphinxupquote{COQ\_COLORS}}, the predefined attributes are ignored.

\phantomsection\label{\detokenize{practical-tools/coq-commands:ocamlrunparam}}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\$OCAMLRUNPARAM}}, described
\sphinxhref{https://caml.inria.fr/pub/docs/manual-ocaml/runtime.html\#s:ocamlrun-options}{here}%
\begin{footnote}[59]\sphinxAtStartFootnote
\sphinxnolinkurl{https://caml.inria.fr/pub/docs/manual-ocaml/runtime.html\#s:ocamlrun-options}
%
\end{footnote},
can be used to specify certain runtime and memory usage parameters.  In most cases,
experimenting with these settings will likely not cause a significant performance difference
and should be harmless.

\sphinxAtStartPar
If the variable is not set, Coq uses the
\sphinxhref{https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html\#TYPEcontrol}{default values}%
\begin{footnote}[60]\sphinxAtStartFootnote
\sphinxnolinkurl{https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html\#TYPEcontrol}
%
\end{footnote},
except that \sphinxcode{\sphinxupquote{space\_overhead}} is set to 120 and \sphinxcode{\sphinxupquote{minor\_heap\_size}} is set to 32Mwords
(256MB with 64\sphinxhyphen{}bit executables or 128MB with 32\sphinxhyphen{}bit executables).


\paragraph{By command line options}
\label{\detokenize{practical-tools/coq-commands:by-command-line-options}}\label{\detokenize{practical-tools/coq-commands:command-line-options}}
\sphinxAtStartPar
The following command\sphinxhyphen{}line options are recognized by the commands \sphinxcode{\sphinxupquote{coqc}}
and \sphinxcode{\sphinxupquote{coqtop}}, unless stated otherwise:
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}I \sphinxstyleemphasis{directory}, \sphinxhyphen{}include \sphinxstyleemphasis{directory}}] \leavevmode
\sphinxAtStartPar
Add physical path \sphinxstyleemphasis{directory}
to the OCaml loadpath.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
{\hyperref[\detokenize{language/core/modules: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[{\sphinxhyphen{}Q \sphinxstyleemphasis{directory dirpath}}] \leavevmode
\sphinxAtStartPar
Add physical path \sphinxstyleemphasis{directory} to the list of
directories where Coq looks for a file and bind it to the logical
directory \sphinxstyleemphasis{dirpath}. The subdirectory structure of \sphinxstyleemphasis{directory} is
recursively available from Coq using absolute names (extending the
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}} prefix) (see Section {\hyperref[\detokenize{language/core/modules:qualified-names}]{\sphinxcrossref{\DUrole{std,std-ref}{Qualified identifiers}}}}). Note that only those
subdirectories and files which obey the lexical conventions of what is
an \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} are taken into account. Conversely, the
underlying file systems or operating systems may be more restrictive
than Coq. While Linux’s ext4 file system supports any 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:}
\nopagebreak


\sphinxAtStartPar
Section {\hyperref[\detokenize{language/core/modules:names-of-libraries}]{\sphinxcrossref{\DUrole{std,std-ref}{Names of libraries}}}}.



\item[{\sphinxhyphen{}R \sphinxstyleemphasis{directory dirpath}}] \leavevmode
\sphinxAtStartPar
Do as \sphinxcode{\sphinxupquote{\sphinxhyphen{}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 Coq using
short or partially qualified names.


\sphinxstrong{See also:}
\nopagebreak


\sphinxAtStartPar
Section {\hyperref[\detokenize{language/core/modules:names-of-libraries}]{\sphinxcrossref{\DUrole{std,std-ref}{Names of libraries}}}}.



\item[{\sphinxhyphen{}top \sphinxstyleemphasis{dirpath}}] \leavevmode
\sphinxAtStartPar
Set the logical module name to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}} for the
\sphinxcode{\sphinxupquote{coqtop}} interactive session. If no module name is specified,
\sphinxcode{\sphinxupquote{coqtop}} will default to \sphinxcode{\sphinxupquote{Top}}. \sphinxcode{\sphinxupquote{coqc}} does not accept this option
because the logical module name is inferred from the name of
the input file and the corresponding \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}} / \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}} options.

\item[{\sphinxhyphen{}exclude\sphinxhyphen{}dir \sphinxstyleemphasis{directory}}] \leavevmode
\sphinxAtStartPar
Exclude any subdirectory named \sphinxstyleemphasis{directory}
while processing options such as \sphinxhyphen{}R and \sphinxhyphen{}Q. By default, only the
conventional version control management directories named CVS
and\_darcs are excluded.

\item[{\sphinxhyphen{}nois, \sphinxhyphen{}noinit}] \leavevmode
\sphinxAtStartPar
Start from an empty state instead of loading the \sphinxcode{\sphinxupquote{Init.Prelude}}
module.

\item[{\sphinxhyphen{}init\sphinxhyphen{}file \sphinxstyleemphasis{file}}] \leavevmode
\sphinxAtStartPar
Load \sphinxstyleemphasis{file} as the resource file instead of
loading the default resource file from the standard configuration
directories.

\item[{\sphinxhyphen{}q}] \leavevmode
\sphinxAtStartPar
Do not to load the default resource file.

\item[{\sphinxhyphen{}l \sphinxstyleemphasis{file}, \sphinxhyphen{}load\sphinxhyphen{}vernac\sphinxhyphen{}source \sphinxstyleemphasis{file}}] \leavevmode
\sphinxAtStartPar
Load and execute the Coq
script from \sphinxstyleemphasis{file.v}.

\item[{\sphinxhyphen{}lv \sphinxstyleemphasis{file}, \sphinxhyphen{}load\sphinxhyphen{}vernac\sphinxhyphen{}source\sphinxhyphen{}verbose \sphinxstyleemphasis{file}}] \leavevmode
\sphinxAtStartPar
Load and execute the
Coq script from \sphinxstyleemphasis{file.v}. Write its contents to the standard output as
it is executed.

\item[{\sphinxhyphen{}load\sphinxhyphen{}vernac\sphinxhyphen{}object \sphinxstyleemphasis{qualid}}] \leavevmode
\sphinxAtStartPar
Load Coq compiled library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}. This
is equivalent to running {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.

\phantomsection\label{\detokenize{practical-tools/coq-commands:interleave-command-line}}
\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Note that the relative order of this command\sphinxhyphen{}line option and its
variants (\sphinxcode{\sphinxupquote{\sphinxhyphen{}rfrom}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}ri}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}re}}, etc.)  and of the \sphinxcode{\sphinxupquote{\sphinxhyphen{}set}} and
\sphinxcode{\sphinxupquote{\sphinxhyphen{}unset}} options matters since the various {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Export}}}}}, {\hyperref[\detokenize{language/core/basic:coq:cmd.Set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Set}}}}} and
{\hyperref[\detokenize{language/core/basic:coq:cmd.Unset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unset}}}}} commands will be executed in the order specified on
the command\sphinxhyphen{}line.
\end{sphinxadmonition}

\item[{\sphinxhyphen{}rfrom \sphinxstyleemphasis{dirpath qualid}}] \leavevmode
\sphinxAtStartPar
Load Coq compiled library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.
This is equivalent to running {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{From}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}} {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.
See the {\hyperref[\detokenize{practical-tools/coq-commands:interleave-command-line}]{\sphinxcrossref{\DUrole{std,std-ref}{note above}}}} regarding the order
of command\sphinxhyphen{}line options.

\item[{\sphinxhyphen{}ri \sphinxstyleemphasis{qualid}, \sphinxhyphen{}require\sphinxhyphen{}import \sphinxstyleemphasis{qualid}}] \leavevmode
\sphinxAtStartPar
Load Coq compiled library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} and import it.
This is equivalent to running {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.
See the {\hyperref[\detokenize{practical-tools/coq-commands:interleave-command-line}]{\sphinxcrossref{\DUrole{std,std-ref}{note above}}}} regarding the order
of command\sphinxhyphen{}line options.

\item[{\sphinxhyphen{}re \sphinxstyleemphasis{qualid}, \sphinxhyphen{}require\sphinxhyphen{}export \sphinxstyleemphasis{qualid}}] \leavevmode
\sphinxAtStartPar
Load Coq compiled library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} and transitively import it.
This is equivalent to running {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Export}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.
See the {\hyperref[\detokenize{practical-tools/coq-commands:interleave-command-line}]{\sphinxcrossref{\DUrole{std,std-ref}{note above}}}} regarding the order
of command\sphinxhyphen{}line options.

\item[{\sphinxhyphen{}rifrom \sphinxstyleemphasis{dirpath qualid}, \sphinxhyphen{}require\sphinxhyphen{}import\sphinxhyphen{}from \sphinxstyleemphasis{dirpath qualid}}] \leavevmode
\sphinxAtStartPar
Load Coq compiled library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} and import it.  This is
equivalent to running {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{From}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}}
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.  See the
{\hyperref[\detokenize{practical-tools/coq-commands:interleave-command-line}]{\sphinxcrossref{\DUrole{std,std-ref}{note above}}}} regarding the order of
command\sphinxhyphen{}line options.

\item[{\sphinxhyphen{}refrom \sphinxstyleemphasis{dirpath qualid}, \sphinxhyphen{}require\sphinxhyphen{}export\sphinxhyphen{}from \sphinxstyleemphasis{dirpath qualid}}] \leavevmode
\sphinxAtStartPar
Load Coq compiled library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} and transitively import it.
This is equivalent to running {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{From}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-dirpath}]{\sphinxcrossref{\DUrole{hole}{dirpath}}}}}}} {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.From-_u2026-Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Export}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.
See the {\hyperref[\detokenize{practical-tools/coq-commands:interleave-command-line}]{\sphinxcrossref{\DUrole{std,std-ref}{note above}}}} regarding the
order of command\sphinxhyphen{}line options.

\item[{\sphinxhyphen{}batch}] \leavevmode
\sphinxAtStartPar
Exit just after argument parsing. Available for \sphinxcode{\sphinxupquote{coqtop}} only.

\item[{\sphinxhyphen{}verbose}] \leavevmode
\sphinxAtStartPar
Output the content of the input file as it is compiled.
This option is available for \sphinxcode{\sphinxupquote{coqc}} only.

\item[{\sphinxhyphen{}native\sphinxhyphen{}compiler (yes|no|ondemand)}] \leavevmode
\sphinxAtStartPar
Enable the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}
reduction machine and precompilation to \sphinxcode{\sphinxupquote{.cmxs}} files for future use
by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}.
Setting \sphinxcode{\sphinxupquote{yes}} enables {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}; it also causes Coq
to precompile the native code for future use; all dependencies need
to have been precompiled beforehand. Setting \sphinxcode{\sphinxupquote{no}} disables
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} which defaults back to {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}}; no files are precompiled.
Setting \sphinxcode{\sphinxupquote{ondemand}} enables {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}
but disables precompilation; all missing dependencies will be recompiled
every time {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} is called.

\phantomsection\label{\detokenize{practical-tools/coq-commands:native-compiler-options}}
\sphinxAtStartPar
\DUrole{versionmodified,deprecated}{Deprecated since version 8.14: }This flag has been deprecated in favor of the {\hyperref[\detokenize{practical-tools/utilities:coqnative}]{\sphinxcrossref{\DUrole{std,std-ref}{Split compilation of native computation files}}}} binary. The
toolchain has been adapted to transparently rely on the latter, so if you
use {\hyperref[\detokenize{practical-tools/utilities:coq-makefile}]{\sphinxcrossref{\DUrole{std,std-ref}{Building a Coq project with coq\_makefile}}}} there is nothing to do. Otherwise you should
substitute calls to \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}native\sphinxhyphen{}compiler yes}} to calls to \sphinxcode{\sphinxupquote{coqc}} followed
by \sphinxcode{\sphinxupquote{coqnative}} on the resulting \sphinxcode{\sphinxupquote{vo}} file.

\sphinxAtStartPar
\DUrole{versionmodified,changed}{Changed in version 8.13: }The default value is set at configure time,
\sphinxcode{\sphinxupquote{\sphinxhyphen{}config}} can be used to retrieve it.
All this can be summarized in the following table:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|T|}
\hline
\sphinxstyletheadfamily 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{configure}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{coqc}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{native\_compute}}
&\sphinxstyletheadfamily 
\sphinxAtStartPar
outcome
&\sphinxstyletheadfamily 
\sphinxAtStartPar
requirements
\\
\hline
\sphinxAtStartPar
yes
&
\sphinxAtStartPar
yes (default)
&
\sphinxAtStartPar
native\_compute
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{.cmxs}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{.cmxs}} of deps
\\
\hline
\sphinxAtStartPar
yes
&
\sphinxAtStartPar
no
&
\sphinxAtStartPar
vm\_compute
&
\sphinxAtStartPar
none
&
\sphinxAtStartPar
none
\\
\hline
\sphinxAtStartPar
yes
&
\sphinxAtStartPar
ondemand
&
\sphinxAtStartPar
native\_compute
&
\sphinxAtStartPar
none
&
\sphinxAtStartPar
none
\\
\hline
\sphinxAtStartPar
no
&
\sphinxAtStartPar
yes, no, ondemand
&
\sphinxAtStartPar
vm\_compute
&
\sphinxAtStartPar
none
&
\sphinxAtStartPar
none
\\
\hline
\sphinxAtStartPar
ondemand
&
\sphinxAtStartPar
yes
&
\sphinxAtStartPar
native\_compute
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{.cmxs}}
&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{.cmxs}} of deps
\\
\hline
\sphinxAtStartPar
ondemand
&
\sphinxAtStartPar
no
&
\sphinxAtStartPar
vm\_compute
&
\sphinxAtStartPar
none
&
\sphinxAtStartPar
none
\\
\hline
\sphinxAtStartPar
ondemand
&
\sphinxAtStartPar
ondemand (default)
&
\sphinxAtStartPar
native\_compute
&
\sphinxAtStartPar
none
&
\sphinxAtStartPar
none
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\item[{\sphinxhyphen{}native\sphinxhyphen{}output\sphinxhyphen{}dir}] \leavevmode
\sphinxAtStartPar
Set the directory in which to put the aforementioned
\sphinxcode{\sphinxupquote{.cmxs}} for {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}. Defaults to \sphinxcode{\sphinxupquote{.coq\sphinxhyphen{}native}}.

\item[{\sphinxhyphen{}vos}] \leavevmode
\sphinxAtStartPar
Indicate Coq to skip the processing of opaque proofs
(i.e., proofs ending with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Admitted}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Admitted}}}}}), output a \sphinxcode{\sphinxupquote{.vos}} files
instead of a \sphinxcode{\sphinxupquote{.vo}} file, and to load \sphinxcode{\sphinxupquote{.vos}} files instead of \sphinxcode{\sphinxupquote{.vo}} files
when interpreting {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} commands.

\item[{\sphinxhyphen{}vok}] \leavevmode
\sphinxAtStartPar
Indicate Coq to check a file completely, to load \sphinxcode{\sphinxupquote{.vos}} files instead
of \sphinxcode{\sphinxupquote{.vo}} files when interpreting {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} commands, and to output an empty
\sphinxcode{\sphinxupquote{.vok}} files upon success instead of writing a \sphinxcode{\sphinxupquote{.vo}} file.

\item[{\sphinxhyphen{}w (all|none|w₁,…,wₙ)}] \leavevmode
\sphinxAtStartPar
Configure the display of warnings. This
option expects all, none or a comma\sphinxhyphen{}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[{\sphinxhyphen{}color (on|off|auto)}] \leavevmode
\sphinxAtStartPar
\sphinxstyleemphasis{Coqtop only}.  Enable or disable color output.
Default is auto, meaning color is shown only if
the output channel supports ANSI escape sequences.

\item[{\sphinxhyphen{}diffs (on|off|removed)}] \leavevmode
\sphinxAtStartPar
\sphinxstyleemphasis{Coqtop only}.  Controls highlighting of differences
between proof steps.  \sphinxcode{\sphinxupquote{on}} highlights added tokens, \sphinxcode{\sphinxupquote{removed}} highlights both added and
removed tokens.  Requires that \sphinxcode{\sphinxupquote{\sphinxhyphen{}color}} is enabled.  (see Section
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:showing-diffs}]{\sphinxcrossref{\DUrole{std,std-ref}{Showing differences between proof steps}}}}).

\item[{\sphinxhyphen{}beautify}] \leavevmode
\sphinxAtStartPar
Pretty\sphinxhyphen{}print each command to \sphinxstyleemphasis{file.beautified} when
compiling \sphinxstyleemphasis{file.v}, in order to get old\sphinxhyphen{}fashioned
syntax/definitions/notations.

\item[{\sphinxhyphen{}emacs, \sphinxhyphen{}ide\sphinxhyphen{}slave}] \leavevmode
\sphinxAtStartPar
Start a special toplevel to communicate with a
specific IDE.

\item[{\sphinxhyphen{}impredicative\sphinxhyphen{}set}] \leavevmode
\sphinxAtStartPar
Change the logical theory of Coq by declaring the
sort \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} impredicative.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
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[{\sphinxhyphen{}type\sphinxhyphen{}in\sphinxhyphen{}type}] \leavevmode
\sphinxAtStartPar
Collapse the universe hierarchy of Coq.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
This makes the logic inconsistent.
\end{sphinxadmonition}

\item[{\sphinxhyphen{}mangle\sphinxhyphen{}names \sphinxstyleemphasis{ident}}] \leavevmode
\sphinxAtStartPar
\sphinxstyleemphasis{Experimental.} Do not depend on this option. Replace
Coq's auto\sphinxhyphen{}generated name scheme with names of the form \sphinxstyleemphasis{ident0}, \sphinxstyleemphasis{ident1},
etc. Within Coq, the {\hyperref[\detokenize{proof-engine/tactics:coq:flag.Mangle-Names}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Mangle Names}}}}} flag turns this behavior on,
and the {\hyperref[\detokenize{proof-engine/tactics:coq:opt.Mangle-Names-Prefix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Mangle Names Prefix}}}}} option sets the prefix to use. This feature
is intended to be used as a linter for developments that want to be robust to
changes in the auto\sphinxhyphen{}generated name scheme. The options are provided to
facilitate tracking down problems.

\item[{\sphinxhyphen{}set \sphinxstyleemphasis{string}}] \leavevmode
\sphinxAtStartPar
Enable flags and set options. \sphinxstyleemphasis{string} should be
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}=value}}}, the value is interpreted according to the
type of the option. For flags \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}=true}}}. For instance \sphinxcode{\sphinxupquote{\sphinxhyphen{}set "Universe Polymorphism"}}
will enable {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}}. Note that the quotes are
shell syntax, Coq does not see them.
See the {\hyperref[\detokenize{practical-tools/coq-commands:interleave-command-line}]{\sphinxcrossref{\DUrole{std,std-ref}{note above}}}} regarding the order
of command\sphinxhyphen{}line options.

\item[{\sphinxhyphen{}unset \sphinxstyleemphasis{string}}] \leavevmode
\sphinxAtStartPar
As \sphinxcode{\sphinxupquote{\sphinxhyphen{}set}} but used to disable options and flags.
\sphinxstyleemphasis{string} must be \sphinxcode{\sphinxupquote{\DUrole{notation}{"{\hyperref[\detokenize{language/core/basic:grammar-token-setting_name}]{\sphinxcrossref{\DUrole{hole}{setting\_name}}}}"}}}.
See the {\hyperref[\detokenize{practical-tools/coq-commands:interleave-command-line}]{\sphinxcrossref{\DUrole{std,std-ref}{note above}}}} regarding the order
of command\sphinxhyphen{}line options.

\item[{\sphinxhyphen{}compat \sphinxstyleemphasis{version}}] \leavevmode
\sphinxAtStartPar
Load a file that sets a few options to maintain
partial backward\sphinxhyphen{}compatibility with a previous version.  This is
equivalent to {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require-Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}} \sphinxcode{\sphinxupquote{Coq.Compat.CoqXXX}} with \sphinxcode{\sphinxupquote{XXX}}
one of the last three released versions (including the current
version).  Note that the {\hyperref[\detokenize{practical-tools/coq-commands:interleave-command-line}]{\sphinxcrossref{\DUrole{std,std-ref}{explanations above}}}} regarding the order of command\sphinxhyphen{}line
options apply, and this could be relevant if you are resetting some
of the compatibility options.

\item[{\sphinxhyphen{}dump\sphinxhyphen{}glob \sphinxstyleemphasis{file}}] \leavevmode
\sphinxAtStartPar
Dump references for global names in file \sphinxstyleemphasis{file}
(to be used by coqdoc, see {\hyperref[\detokenize{using/tools/coqdoc: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[{\sphinxhyphen{}no\sphinxhyphen{}glob}] \leavevmode
\sphinxAtStartPar
Disable the dumping of references for global names.

\item[{\sphinxhyphen{}image \sphinxstyleemphasis{file}}] \leavevmode
\sphinxAtStartPar
Set the binary image to be used by \sphinxcode{\sphinxupquote{coqc}} to be \sphinxstyleemphasis{file}
instead of the standard one. Not of general use.

\item[{\sphinxhyphen{}bindir \sphinxstyleemphasis{directory}}] \leavevmode
\sphinxAtStartPar
Set the directory containing Coq binaries to be
used by \sphinxcode{\sphinxupquote{coqc}}. It is equivalent to doing export COQBIN= \sphinxstyleemphasis{directory}
before launching \sphinxcode{\sphinxupquote{coqc}}.

\item[{\sphinxhyphen{}where}] \leavevmode
\sphinxAtStartPar
Print the location of Coq’s standard library and exit.

\item[{\sphinxhyphen{}config}] \leavevmode
\sphinxAtStartPar
Print the locations of Coq’s binaries, dependencies, and
libraries, then exit.

\item[{\sphinxhyphen{}filteropts}] \leavevmode
\sphinxAtStartPar
Print the list of command line arguments that \sphinxcode{\sphinxupquote{coqtop}} has
recognized as options and exit.

\item[{\sphinxhyphen{}v}] \leavevmode
\sphinxAtStartPar
Print Coq’s version and exit.

\item[{\sphinxhyphen{}list\sphinxhyphen{}tags}] \leavevmode
\sphinxAtStartPar
Print the highlight tags known by Coq as well as their
currently associated color and exit.

\item[{\sphinxhyphen{}h, \sphinxhyphen{}\sphinxhyphen{}help}] \leavevmode
\sphinxAtStartPar
Print a short usage and exit.

\end{description}\end{quote}


\subsubsection{Compiled interfaces (produced using \sphinxstyleliteralintitle{\sphinxupquote{\sphinxhyphen{}vos}})}
\label{\detokenize{practical-tools/coq-commands:compiled-interfaces-produced-using-vos}}\label{\detokenize{practical-tools/coq-commands:compiled-interfaces}}
\sphinxAtStartPar
Compiled interfaces help saving time while developing Coq formalizations,
by compiling the formal statements exported by a library independently of
the proofs that it contains.
\begin{quote}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
Compiled interfaces should only be used for development purposes.
At the end of the day, one still needs to proof check all files
by producing standard \sphinxcode{\sphinxupquote{.vo}} files. (Technically, when using \sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}},
fewer universe constraints are collected.)
Moreover, this feature is still experimental, it may be subject to
change without prior notice.
\end{sphinxadmonition}
\end{quote}

\sphinxAtStartPar
\sphinxstylestrong{Principle.}

\sphinxAtStartPar
The compilation using \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}vos foo.v}} produces a file called \sphinxcode{\sphinxupquote{foo.vos}},
which is similar to \sphinxcode{\sphinxupquote{foo.vo}} except that all opaque proofs are skipped in
the compilation process.

\sphinxAtStartPar
The compilation using \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}vok foo.v}} checks that the file \sphinxcode{\sphinxupquote{foo.v}}
correctly compiles, including all its opaque proofs. If the compilation
succeeds, then the output is a file called \sphinxcode{\sphinxupquote{foo.vok}}, with empty contents.
This file is only a placeholder indicating that \sphinxcode{\sphinxupquote{foo.v}} has been successfully
compiled. (This placeholder is useful for build systems such as \sphinxcode{\sphinxupquote{make}}.)

\sphinxAtStartPar
When compiling a file \sphinxcode{\sphinxupquote{bar.v}} that depends on \sphinxcode{\sphinxupquote{foo.v}} (for example via
a \sphinxcode{\sphinxupquote{Require Foo.}} command), if the compilation command is \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}vos bar.v}}
or \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}vok bar.v}}, then the file \sphinxcode{\sphinxupquote{foo.vos}} gets loaded (instead of
\sphinxcode{\sphinxupquote{foo.vo}}). A special case is if file \sphinxcode{\sphinxupquote{foo.vos}} exists and has empty
contents, and \sphinxcode{\sphinxupquote{foo.vo}} exists, then \sphinxcode{\sphinxupquote{foo.vo}} is loaded.

\sphinxAtStartPar
Appart from the aforementioned case where \sphinxcode{\sphinxupquote{foo.vo}} can be loaded in place
of \sphinxcode{\sphinxupquote{foo.vos}}, in general the \sphinxcode{\sphinxupquote{.vos}} and \sphinxcode{\sphinxupquote{.vok}} files live totally
independently from the \sphinxcode{\sphinxupquote{.vo}} files.

\sphinxAtStartPar
\sphinxstylestrong{Dependencies generated by ``coq\_makefile``.}

\sphinxAtStartPar
The files \sphinxcode{\sphinxupquote{foo.vos}} and \sphinxcode{\sphinxupquote{foo.vok}} both depend on \sphinxcode{\sphinxupquote{foo.v}}.

\sphinxAtStartPar
Furthermore, if a file \sphinxcode{\sphinxupquote{foo.v}} requires \sphinxcode{\sphinxupquote{bar.v}}, then \sphinxcode{\sphinxupquote{foo.vos}}
and \sphinxcode{\sphinxupquote{foo.vok}} also depend on \sphinxcode{\sphinxupquote{bar.vos}}.

\sphinxAtStartPar
Note, however, that \sphinxcode{\sphinxupquote{foo.vok}} does not depend on \sphinxcode{\sphinxupquote{bar.vok}}.
Hence, as detailed further, parallel compilation of proofs is possible.

\sphinxAtStartPar
In addition, \sphinxcode{\sphinxupquote{coq\_makefile}} generates for a file \sphinxcode{\sphinxupquote{foo.v}} a target
\sphinxcode{\sphinxupquote{foo.required\_vos}} which depends on the list of \sphinxcode{\sphinxupquote{.vos}} files that
\sphinxcode{\sphinxupquote{foo.vos}} depends upon (excluding \sphinxcode{\sphinxupquote{foo.vos}} itself). As explained
next, the purpose of this target is to be able to request the minimal
working state for editing interactively the file \sphinxcode{\sphinxupquote{foo.v}}.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
When writing a custom build system, be aware that \sphinxcode{\sphinxupquote{coqdep}} only
produces dependencies related to \sphinxcode{\sphinxupquote{.vos}} and \sphinxcode{\sphinxupquote{.vok}} if the
\sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} command line flag is passed. This is to maintain
compatibility with dune (see \sphinxhref{https://github.com/ocaml/dune/issues/2842}{ocaml/dune\#2642 on github}%
\begin{footnote}[61]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/ocaml/dune/issues/2842}
%
\end{footnote}).
\end{sphinxadmonition}

\sphinxAtStartPar
\sphinxstylestrong{Typical compilation of a set of file using a build system.}

\sphinxAtStartPar
Assume a file \sphinxcode{\sphinxupquote{foo.v}} that depends on two files \sphinxcode{\sphinxupquote{f1.v}} and \sphinxcode{\sphinxupquote{f2.v}}. The
command \sphinxcode{\sphinxupquote{make foo.required\_vos}} will compile \sphinxcode{\sphinxupquote{f1.v}} and \sphinxcode{\sphinxupquote{f2.v}} using
the option \sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} to skip the proofs, producing \sphinxcode{\sphinxupquote{f1.vos}} and \sphinxcode{\sphinxupquote{f2.vos}}.
At this point, one is ready to work interactively on the file \sphinxcode{\sphinxupquote{foo.v}}, even
though it was never needed to compile the proofs involved in the files \sphinxcode{\sphinxupquote{f1.v}}
and \sphinxcode{\sphinxupquote{f2.v}}.

\sphinxAtStartPar
Assume a set of files \sphinxcode{\sphinxupquote{f1.v ... fn.v}} with linear dependencies. The command
\sphinxcode{\sphinxupquote{make vos}} enables compiling the statements (i.e. excluding the proofs) in all
the files. Next, \sphinxcode{\sphinxupquote{make \sphinxhyphen{}j vok}} enables compiling all the proofs in parallel.
Thus, calling \sphinxcode{\sphinxupquote{make \sphinxhyphen{}j vok}} directly enables taking advantage of a maximal
amount of parallelism during the compilation of the set of files.

\sphinxAtStartPar
Note that this comes at the cost of parsing and typechecking all definitions
twice, once for the \sphinxcode{\sphinxupquote{.vos}} file and once for the \sphinxcode{\sphinxupquote{.vok}} file. However, if
files contain nontrivial proofs, or if the files have many linear chains of
dependencies, or if one has many cores available, compilation should be faster
overall.

\sphinxAtStartPar
\sphinxstylestrong{Need for ``Proof using``}

\sphinxAtStartPar
When a theorem is part of a section, typechecking the statement of this theorem
might be insufficient for deducing the type of this statement as of at the end
of the section. Indeed, the proof of the theorem could make use of section
variables or section hypotheses that are not mentioned in the statement of the
theorem.

\sphinxAtStartPar
For this reason, proofs inside section should begin with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof-using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof using}}}}}
instead of {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}}, where after the \sphinxcode{\sphinxupquote{using}} clause one should provide
the list of the names of the section variables that are required for the proof
but are not involved in the typechecking of the statement. Note that it is safe
to write \sphinxcode{\sphinxupquote{Proof using.}} instead of \sphinxcode{\sphinxupquote{Proof.}} also for proofs that are not
within a section.
\index{You should use the “Proof using {[}...{]}.” syntax instead of “Proof.” to enable skipping this proof which is located inside a section. Give as argument to “Proof using” the list of section variables that are not needed to typecheck the statement but that are required by the proof (warning)@\spxentry{You should use the “Proof using {[}...{]}.” syntax instead of “Proof.” to enable skipping this proof which is located inside a section. Give as argument to “Proof using” the list of section variables that are not needed to typecheck the statement but that are required by the proof}\spxextra{warning}}

\begin{savenotes}\begin{fulllineitems}
\phantomsection\label{\detokenize{practical-tools/coq-commands:coq:warn.You-should-use-the-_u201cProof-using-_..._._u201d-syntax-instead-of-_u201cProof._u201d-to-enable-skipping-this-proof-which-is-located-inside-a-section.-Give-as-argument-to-_u201cProof-using_u201d-the-list-of-section-variables-that-are-not-needed-to-typecheck-the-statement-but-that-are-required-by-the-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{You~should~use~the~“Proof~using~{[}...{]}.”~syntax~instead~of~“Proof.”~to~enable~skipping~this~proof~which~is~located~inside~a~section.~Give~as~argument~to~“Proof~using”~the~list~of~section~variables~that~are~not~needed~to~typecheck~the~statement~but~that~are~required~by~the~proof.}}}}
\sphinxAtStartPar
If Coq is invoked using the \sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} option, whenever it finds the
command \sphinxcode{\sphinxupquote{Proof.}} inside a section, it will compile the proof, that is,
refuse to skip it, and it will raise a warning. To disable the warning, one
may pass the flag \sphinxcode{\sphinxupquote{\sphinxhyphen{}w \sphinxhyphen{}proof\sphinxhyphen{}without\sphinxhyphen{}using\sphinxhyphen{}in\sphinxhyphen{}section}}.

\end{fulllineitems}\end{savenotes}


\sphinxAtStartPar
\sphinxstylestrong{Interaction with standard compilation}

\sphinxAtStartPar
When compiling a file \sphinxcode{\sphinxupquote{foo.v}} using \sphinxcode{\sphinxupquote{coqc}} in the standard way (i.e., without
\sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} nor \sphinxcode{\sphinxupquote{\sphinxhyphen{}vok}}), an empty file \sphinxcode{\sphinxupquote{foo.vos}} and an empty file \sphinxcode{\sphinxupquote{foo.vok}}
are created in addition to the regular output file \sphinxcode{\sphinxupquote{foo.vo}}.
If \sphinxcode{\sphinxupquote{coqc}} is subsequently invoked on some other file \sphinxcode{\sphinxupquote{bar.v}} using option
\sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} or \sphinxcode{\sphinxupquote{\sphinxhyphen{}vok}}, and that \sphinxcode{\sphinxupquote{bar.v}} requires \sphinxcode{\sphinxupquote{foo.v}}, if Coq finds an
empty file \sphinxcode{\sphinxupquote{foo.vos}}, then it will load \sphinxcode{\sphinxupquote{foo.vo}} instead of \sphinxcode{\sphinxupquote{foo.vos}}.

\sphinxAtStartPar
The purpose of this feature is to allow users to benefit from the \sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}}
option even if they depend on libraries that were compiled in the traditional
manner (i.e., never compiled using the \sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} option).


\subsubsection{Compiled libraries checker (coqchk)}
\label{\detokenize{practical-tools/coq-commands:compiled-libraries-checker-coqchk}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{coqchk}} command takes a list of library paths as argument, described either
by their logical name or by their physical filename, which 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.

\sphinxAtStartPar
Note that non\sphinxhyphen{}logical information is not checked. By logical
information, we mean the type and optional {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}} associated with 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.

\sphinxAtStartPar
This tool can be used for several purposes. One is to check that a
compiled library provided by a third\sphinxhyphen{}party has not been forged and
that loading it cannot introduce inconsistencies %
\begin{footnote}[62]\sphinxAtStartFootnote
Ill\sphinxhyphen{}formed non\sphinxhyphen{}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\sphinxhyphen{}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.

\sphinxAtStartPar
Command\sphinxhyphen{}line options \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}where}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}impredicative\sphinxhyphen{}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{\sphinxhyphen{}Q}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}} have exactly the same meaning.
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}norec \sphinxstyleemphasis{module}}] \leavevmode
\sphinxAtStartPar
Check \sphinxstyleemphasis{module} but do not check its dependencies.

\item[{\sphinxhyphen{}admit \sphinxstyleemphasis{module}}] \leavevmode
\sphinxAtStartPar
Do not check \sphinxstyleemphasis{module} and any of its dependencies,
unless explicitly required.

\item[{\sphinxhyphen{}o}] \leavevmode
\sphinxAtStartPar
At exit, print a summary about the context. List the names of all
assumptions and variables (constants without a {\hyperref[\detokenize{language/core/definitions:term-body}]{\sphinxtermref{\DUrole{xref,std,std-term}{body}}}}).

\item[{\sphinxhyphen{}silent}] \leavevmode
\sphinxAtStartPar
Do not write progress information to the standard output.

\end{description}\end{quote}

\sphinxAtStartPar
Environment variable \sphinxcode{\sphinxupquote{\$COQLIB}} can be set to override the location of
the standard library.

\sphinxAtStartPar
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{\sphinxhyphen{}norec N}}, and \sphinxcode{\sphinxupquote{\sphinxhyphen{}admit A}}. Let us write \(\overline{S}\) for the
set of reflexive transitive dependencies of set \(S\). Then:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Modules \(C = \overline{M} \backslash \overline{A} \cup M \cup N\) are loaded and type checked before being added
to the context.

\item {} 
\sphinxAtStartPar
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}

\sphinxAtStartPar
As a rule of thumb, \sphinxhyphen{}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 \sphinxhyphen{}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.


\subsection{Utilities}
\label{\detokenize{practical-tools/utilities:utilities}}\label{\detokenize{practical-tools/utilities:id1}}\label{\detokenize{practical-tools/utilities::doc}}
\sphinxAtStartPar
The distribution provides utilities to simplify some tedious works
beside proof development, tactics writing or documentation.


\subsubsection{Using Coq as a library}
\label{\detokenize{practical-tools/utilities:using-coq-as-a-library}}
\sphinxAtStartPar
In previous versions, \sphinxcode{\sphinxupquote{coqmktop}} was used to build custom
toplevels \sphinxhyphen{} for example for better debugging or custom static
linking. Nowadays, the preferred method is to use \sphinxcode{\sphinxupquote{ocamlfind}}.

\sphinxAtStartPar
The most basic custom toplevel is built using:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZpc{} ocamlfind ocamlopt \PYGZhy{}thread \PYGZhy{}rectypes \PYGZhy{}linkall \PYGZhy{}linkpkg \PYGZbs{}
              \PYGZhy{}package coq.toplevel \PYGZbs{}
              topbin/coqtop\PYGZus{}bin.ml \PYGZhy{}o my\PYGZus{}toplevel.native
\end{sphinxVerbatim}

\sphinxAtStartPar
For example, to statically link \sphinxcode{\sphinxupquote{L}}$_{\text{tac}}$, you can just do:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZpc{} ocamlfind ocamlopt \PYGZhy{}thread \PYGZhy{}rectypes \PYGZhy{}linkall \PYGZhy{}linkpkg \PYGZbs{}
              \PYGZhy{}package coq.toplevel,coq.plugins.ltac \PYGZbs{}
              topbin/coqtop\PYGZus{}bin.ml \PYGZhy{}o my\PYGZus{}toplevel.native
\end{sphinxVerbatim}

\sphinxAtStartPar
and similarly for other plugins.


\subsubsection{Building a Coq project}
\label{\detokenize{practical-tools/utilities:building-a-coq-project}}\label{\detokenize{practical-tools/utilities:building-coq-project}}
\sphinxAtStartPar
As of today it is possible to build Coq projects using two tools:
\begin{itemize}
\item {} 
\sphinxAtStartPar
coq\_makefile, which is distributed by Coq and is based on generating a makefile,

\item {} 
\sphinxAtStartPar
Dune, the standard OCaml build tool, which, since version 1.9, supports building Coq libraries.

\end{itemize}


\paragraph{Building a Coq project with coq\_makefile}
\label{\detokenize{practical-tools/utilities:building-a-coq-project-with-coq-makefile}}\label{\detokenize{practical-tools/utilities:coq-makefile}}
\sphinxAtStartPar
The majority of Coq projects are very similar: a collection of \sphinxcode{\sphinxupquote{.v}}
files and eventually some \sphinxcode{\sphinxupquote{.ml}} ones (a 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{\sphinxhyphen{}R}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}I}}, see {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{command
line options}}}}). Collecting the list of files
and options is the job of the \sphinxcode{\sphinxupquote{\_CoqProject}} file.

\sphinxAtStartPar
A simple example of a \sphinxcode{\sphinxupquote{\_CoqProject}} file follows:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}R theories/ MyCode
\PYGZhy{}arg \PYGZhy{}w
\PYGZhy{}arg all
theories/foo.v
theories/bar.v
\PYGZhy{}I src/
src/baz.mlg
src/bazaux.ml
src/qux\PYGZus{}plugin.mlpack
\end{sphinxVerbatim}

\sphinxAtStartPar
where options \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}I}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler}} are natively recognized, as well as
file names. The lines of the form \sphinxcode{\sphinxupquote{\sphinxhyphen{}arg foo}} are used in order to tell
to literally pass an argument \sphinxcode{\sphinxupquote{foo}} to \sphinxcode{\sphinxupquote{coqc}}: in the
example, this allows to pass the two\sphinxhyphen{}word option \sphinxcode{\sphinxupquote{\sphinxhyphen{}w all}} (see
{\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{command line options}}}}).

\sphinxAtStartPar
Note that it is mandatory to specify a \sphinxcode{\sphinxupquote{\sphinxhyphen{}R/\sphinxhyphen{}Q}} flag for your
project, so its modules are properly qualified. Omitting it will
generate object files that are not usable except for expert cases.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler}} option given in the \sphinxcode{\sphinxupquote{\_CoqProject}} file will override
the global one passed at configure time.

\sphinxAtStartPar
CoqIDE, Proof\sphinxhyphen{}General and VSCoq all
understand \sphinxcode{\sphinxupquote{\_CoqProject}} files and can be used to invoke Coq with the desired options.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{coq\_makefile}} utility can be used to set up a build infrastructure
for the Coq project based on makefiles. The recommended way of
invoking \sphinxcode{\sphinxupquote{coq\_makefile}} is the following one:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
coq\PYGZus{}makefile \PYGZhy{}f \PYGZus{}CoqProject \PYGZhy{}o CoqMakefile
\end{sphinxVerbatim}

\sphinxAtStartPar
Such command generates the following files:
\begin{description}
\item[{CoqMakefile}] \leavevmode
\sphinxAtStartPar
is a makefile for \sphinxcode{\sphinxupquote{GNU Make}} with targets to build the project
(e.g. generate .vo or .html files from .v or compile .ml* files)
and install it in the \sphinxcode{\sphinxupquote{user\sphinxhyphen{}contrib}} directory where the Coq
library is installed.

\item[{CoqMakefile.conf}] \leavevmode
\sphinxAtStartPar
contains make variables assignments that reflect
the contents of the \sphinxcode{\sphinxupquote{\_CoqProject}} file as well as the path relevant to
Coq.

\end{description}

\sphinxAtStartPar
Run \sphinxcode{\sphinxupquote{coq\_makefile \sphinxhyphen{}\sphinxhyphen{}help}} for a description of command line options.

\sphinxAtStartPar
The recommended approach is to invoke \sphinxcode{\sphinxupquote{CoqMakefile}} from a standard
\sphinxcode{\sphinxupquote{Makefile}} of the following form:

\begin{sphinxadmonition}{note}{Example}

\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}

\sphinxAtStartPar
The advantage of a wrapper, compared to directly calling the generated
\sphinxcode{\sphinxupquote{Makefile}}, is that it
provides a target independent of the version of Coq to regenerate a
\sphinxcode{\sphinxupquote{Makefile}} specific to the current version of Coq. Additionally, the
master \sphinxcode{\sphinxupquote{Makefile}} can be extended with targets not specific to Coq.
Including the generated makefile with an include directive is
discouraged, since the contents of this file, including variable names and
status of rules, may change in the future.

\sphinxAtStartPar
Use the optional file \sphinxcode{\sphinxupquote{CoqMakefile.local}} to extend
\sphinxcode{\sphinxupquote{CoqMakefile}}. In particular, you can declare custom actions to run
before or after the build process. Similarly you can customize the
install target or even provide new targets. See
{\hyperref[\detokenize{practical-tools/utilities:coqmakefilelocal}]{\sphinxcrossref{\DUrole{std,std-ref}{CoqMakefile.local}}}} for extension\sphinxhyphen{}point documentation. Although
you can use all variables defined in \sphinxcode{\sphinxupquote{CoqMakefile}} in the \sphinxstyleemphasis{recipes}
of rules that you write and in the definitions of any variables that
you assign with \sphinxcode{\sphinxupquote{=}}, many variables are not available for use if you
assign variable values with \sphinxcode{\sphinxupquote{:=}} nor to define the \sphinxstyleemphasis{targets} of
rules nor in top\sphinxhyphen{}level conditionals such as \sphinxcode{\sphinxupquote{ifeq}}. Additionally,
you must use \sphinxhref{https://www.gnu.org/software/make/manual/html\_node/Secondary-Expansion.html}{secondary expansion}%
\begin{footnote}[63]\sphinxAtStartFootnote
\sphinxnolinkurl{https://www.gnu.org/software/make/manual/html\_node/Secondary-Expansion.html}
%
\end{footnote}
to make use of such variables in the prerequisites of rules. To access
variables defined in \sphinxcode{\sphinxupquote{CoqMakefile}} in rule target computation,
top\sphinxhyphen{}level conditionals, and \sphinxcode{\sphinxupquote{:=}} variable assignment, for example to
add new dependencies to compiled outputs, use the optional file
\sphinxcode{\sphinxupquote{CoqMakefile.local\sphinxhyphen{}late}}.  See {\hyperref[\detokenize{practical-tools/utilities:coqmakefilelocallate}]{\sphinxcrossref{\DUrole{std,std-ref}{CoqMakefile.local\sphinxhyphen{}late}}}} for a
non\sphinxhyphen{}exhaustive list of variables.

\sphinxAtStartPar
The extensions of files listed in \sphinxcode{\sphinxupquote{\_CoqProject}} determine
how they are built. In particular:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Coq files must use the \sphinxcode{\sphinxupquote{.v}} extension

\item {} 
\sphinxAtStartPar
OCaml files must use the \sphinxcode{\sphinxupquote{.ml}} or \sphinxcode{\sphinxupquote{.mli}} extension

\item {} 
\sphinxAtStartPar
OCaml files that require pre processing for syntax
extensions (like \sphinxcode{\sphinxupquote{VERNAC EXTEND}}) must use the \sphinxcode{\sphinxupquote{.mlg}} extension

\item {} 
\sphinxAtStartPar
In order to generate a plugin one has to list all 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}

\sphinxAtStartPar
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.


\subparagraph{CoqMakefile.local}
\label{\detokenize{practical-tools/utilities:coqmakefile-local}}\label{\detokenize{practical-tools/utilities:coqmakefilelocal}}
\sphinxAtStartPar
The optional file \sphinxcode{\sphinxupquote{CoqMakefile.local}} is included by the generated
file \sphinxcode{\sphinxupquote{CoqMakefile}}. It can contain two kinds of directives.

\sphinxAtStartPar
\sphinxstylestrong{Variable assignment}

\sphinxAtStartPar
The variable must belong to the variables listed in the \sphinxcode{\sphinxupquote{Parameters}}
section of the generated makefile.  Use
\sphinxcode{\sphinxupquote{CoqMakefile.local\sphinxhyphen{}late}} instead to access more variables. These include:
\begin{quote}\begin{description}
\item[{CAMLPKGS}] \leavevmode
\sphinxAtStartPar
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{\sphinxhyphen{}package yojson}}.

\item[{CAMLFLAGS}] \leavevmode
\sphinxAtStartPar
can be used to specify additional flags to the OCaml
compiler, like \sphinxcode{\sphinxupquote{\sphinxhyphen{}bin\sphinxhyphen{}annot}} or \sphinxcode{\sphinxupquote{\sphinxhyphen{}w}}....

\item[{OCAMLWARN}] \leavevmode
\sphinxAtStartPar
it contains a default of \sphinxcode{\sphinxupquote{\sphinxhyphen{}warn\sphinxhyphen{}error +a\sphinxhyphen{}3}}, useful to modify
this setting; beware this is not recommended for projects in
Coq's CI.

\item[{COQC, COQDEP, COQDOC}] \leavevmode
\sphinxAtStartPar
can be set in order to use alternative binaries
(e.g. wrappers)

\item[{COQ\_SRC\_SUBDIRS}] \leavevmode
\sphinxAtStartPar
can be extended by including other paths in which \sphinxcode{\sphinxupquote{*.cm*}} files
are searched. For example \sphinxcode{\sphinxupquote{COQ\_SRC\_SUBDIRS+=user\sphinxhyphen{}contrib/Unicoq}}
lets you build a plugin containing OCaml code that depends on the
OCaml code of \sphinxcode{\sphinxupquote{Unicoq}}

\item[{COQFLAGS}] \leavevmode
\sphinxAtStartPar
override the flags passed to \sphinxcode{\sphinxupquote{coqc}}. By default \sphinxcode{\sphinxupquote{\sphinxhyphen{}q}}.

\item[{COQEXTRAFLAGS}] \leavevmode
\sphinxAtStartPar
extend the flags passed to \sphinxcode{\sphinxupquote{coqc}}

\item[{COQCHKFLAGS}] \leavevmode
\sphinxAtStartPar
override the flags passed to \sphinxcode{\sphinxupquote{coqchk}}.  By default \sphinxcode{\sphinxupquote{\sphinxhyphen{}silent \sphinxhyphen{}o}}.

\item[{COQCHKEXTRAFLAGS}] \leavevmode
\sphinxAtStartPar
extend the flags passed to \sphinxcode{\sphinxupquote{coqchk}}

\item[{COQDOCFLAGS}] \leavevmode
\sphinxAtStartPar
override the flags passed to \sphinxcode{\sphinxupquote{coqdoc}}. By default \sphinxcode{\sphinxupquote{\sphinxhyphen{}interpolate \sphinxhyphen{}utf8}}.

\item[{COQDOCEXTRAFLAGS}] \leavevmode
\sphinxAtStartPar
extend the flags passed to \sphinxcode{\sphinxupquote{coqdoc}}

\item[{COQLIBINSTALL, COQDOCINSTALL}] \leavevmode
\sphinxAtStartPar
specify where the Coq libraries and documentation will be installed.
By default a combination of \sphinxcode{\sphinxupquote{\$(DESTDIR)}} (if defined) with
\sphinxcode{\sphinxupquote{\$(COQLIB)/user\sphinxhyphen{}contrib}} and \sphinxcode{\sphinxupquote{\$(DOCDIR)/user\sphinxhyphen{}contrib}}.

\end{description}\end{quote}

\sphinxAtStartPar
\sphinxstylestrong{Rule extension}

\sphinxAtStartPar
The following makefile rules can be extended.

\begin{sphinxadmonition}{note}{Example}

\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\sphinxhyphen{}all::}}}] \leavevmode
\sphinxAtStartPar
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\sphinxhyphen{}all::}}}] \leavevmode
\sphinxAtStartPar
run after the \sphinxcode{\sphinxupquote{all}} target. One can use this to run a test
suite, or compile extracted code.

\item[{\sphinxcode{\sphinxupquote{install\sphinxhyphen{}extra::}}}] \leavevmode
\sphinxAtStartPar
run after \sphinxcode{\sphinxupquote{install}}. One can use this to install extra files.

\item[{\sphinxcode{\sphinxupquote{install\sphinxhyphen{}doc::}}}] \leavevmode
\sphinxAtStartPar
One can use this to install extra doc.

\item[{\sphinxcode{\sphinxupquote{uninstall::}}}] \leavevmode
\sphinxAtStartPar


\item[{\sphinxcode{\sphinxupquote{uninstall\sphinxhyphen{}doc::}}}] \leavevmode
\sphinxAtStartPar


\item[{\sphinxcode{\sphinxupquote{clean::}}}] \leavevmode
\sphinxAtStartPar


\item[{\sphinxcode{\sphinxupquote{cleanall::}}}] \leavevmode
\sphinxAtStartPar


\item[{\sphinxcode{\sphinxupquote{archclean::}}}] \leavevmode
\sphinxAtStartPar


\item[{\sphinxcode{\sphinxupquote{merlin\sphinxhyphen{}hook::}}}] \leavevmode
\sphinxAtStartPar
One can append lines to the generated \sphinxcode{\sphinxupquote{.merlin}} file extending this
target.

\end{description}


\subparagraph{CoqMakefile.local\sphinxhyphen{}late}
\label{\detokenize{practical-tools/utilities:coqmakefile-local-late}}\label{\detokenize{practical-tools/utilities:coqmakefilelocallate}}
\sphinxAtStartPar
The optional file \sphinxcode{\sphinxupquote{CoqMakefile.local\sphinxhyphen{}late}} is included at the end of the generated
file \sphinxcode{\sphinxupquote{CoqMakefile}}.  The following is a partial list of accessible variables:
\begin{quote}\begin{description}
\item[{COQ\_VERSION}] \leavevmode
\sphinxAtStartPar
the version of \sphinxcode{\sphinxupquote{coqc}} being used, which can be used to
provide different behavior depending on the Coq version

\item[{COQMAKEFILE\_VERSION}] \leavevmode
\sphinxAtStartPar
the version of Coq used to generate the
Makefile, which can be used to detect version mismatches

\item[{ALLDFILES}] \leavevmode
\sphinxAtStartPar
the list of generated dependency files, which can be used,
for example, to cause \sphinxcode{\sphinxupquote{make}} to recompute dependencies
when files change by writing \sphinxcode{\sphinxupquote{\$(ALLDFILES): myfiles}} or to
indicate that files must be generated before dependencies can
be computed by writing \sphinxcode{\sphinxupquote{\$(ALLDFILES): | mygeneratedfiles}}

\item[{VOFILES, GLOBFILES, CMOFILES, CMXFILES, OFILES, CMAFILES, CMXAFILES, CMIFILES, CMXSFILES}] \leavevmode
\sphinxAtStartPar
lists of files that are generated by various invocations of the compilers

\end{description}\end{quote}

\sphinxAtStartPar
In addition, the following variables may be useful for
deciding what targets to present via \sphinxcode{\sphinxupquote{\$(shell ...)}}; these
variables are already accessible in recipes for rules added in
\sphinxcode{\sphinxupquote{CoqMakefile.local}}, but are only accessible from top\sphinxhyphen{}level \sphinxcode{\sphinxupquote{\$(shell
...)}} invocations in \sphinxcode{\sphinxupquote{CoqMakefile.local\sphinxhyphen{}late}}:
\begin{quote}\begin{description}
\item[{COQC, COQDEP, COQDOC, CAMLC, CAMLOPTC}] \leavevmode
\sphinxAtStartPar
compiler binaries

\item[{COQFLAGS, CAMLFLAGS, COQLIBS, COQDEBUG, OCAMLLIBS}] \leavevmode
\sphinxAtStartPar
flags passed to the Coq or OCaml compilers

\end{description}\end{quote}


\subparagraph{Timing targets and performance testing}
\label{\detokenize{practical-tools/utilities:timing-targets-and-performance-testing}}
\sphinxAtStartPar
The generated \sphinxcode{\sphinxupquote{Makefile}} supports the generation of two kinds of timing
data: per\sphinxhyphen{}file build\sphinxhyphen{}times, and per\sphinxhyphen{}line times for an individual file.

\sphinxAtStartPar
The following targets and Makefile variables allow collection of per\sphinxhyphen{}
file timing data:
\begin{itemize}
\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{TIMED=1}}}] \leavevmode
\sphinxAtStartPar
passing this variable will cause \sphinxcode{\sphinxupquote{make}} to emit a line
describing the user\sphinxhyphen{}space build\sphinxhyphen{}time and peak memory usage for each
file built.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
On \sphinxcode{\sphinxupquote{Mac OS}}, this works best if you’ve installed \sphinxcode{\sphinxupquote{gnu\sphinxhyphen{}time}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For example, the output of \sphinxcode{\sphinxupquote{make TIMED=1}} may look like
this:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
COQDEP Fast.v
COQDEP Slow.v
COQC Slow.v
Slow.vo (user: 0.34 mem: 395448 ko)
COQC Fast.v
Fast.vo (user: 0.01 mem: 45184 ko)
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{description}

\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{pretty\sphinxhyphen{}timed}}}] \leavevmode
\sphinxAtStartPar
this target stores the output of \sphinxcode{\sphinxupquote{make TIMED=1}} into
\sphinxcode{\sphinxupquote{time\sphinxhyphen{}of\sphinxhyphen{}build.log}}, and displays a table of the times and peak
memory usages, sorted from slowest to fastest, which is also
stored in \sphinxcode{\sphinxupquote{time\sphinxhyphen{}of\sphinxhyphen{}build\sphinxhyphen{}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\sphinxhyphen{}timed
TGTS="a.vo b.vo"}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
This target requires \sphinxcode{\sphinxupquote{python}} to build the table.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
This target will \sphinxstyleemphasis{append} to the timing log; if you want a
fresh start, you must remove the file \sphinxcode{\sphinxupquote{time\sphinxhyphen{}of\sphinxhyphen{}build.log}} or
\sphinxcode{\sphinxupquote{run make cleanall}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
By default the table displays user times.  If the build log
contains real times (which it does by default), passing
\sphinxcode{\sphinxupquote{TIMING\_REAL=1}} to \sphinxcode{\sphinxupquote{make pretty\sphinxhyphen{}timed}} will use real times
rather than user times in the table.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Passing \sphinxcode{\sphinxupquote{TIMING\_INCLUDE\_MEM=0}} to \sphinxcode{\sphinxupquote{make}} will result in the
tables not including peak memory usage information.  Passing
\sphinxcode{\sphinxupquote{TIMING\_SORT\_BY\_MEM=1}} to \sphinxcode{\sphinxupquote{make}} will result in the tables
be sorted by peak memory usage rather than by the time taken.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For example, the output of \sphinxcode{\sphinxupquote{make pretty\sphinxhyphen{}timed}} may look like this:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
COQDEP VFILES
COQC Slow.v
Slow.vo (real: 0.52, user: 0.39, sys: 0.12, mem: 394648 ko)
COQC Fast.v
Fast.vo (real: 0.06, user: 0.02, sys: 0.03, mem: 56980 ko)
    Time |  Peak Mem | File Name
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\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.41s | 394648 ko | Total Time / Peak Mem
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\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 | 394648 ko | Slow.vo
0m00.02s |  56980 ko | Fast.vo
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{description}

\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}}}] \leavevmode
\sphinxAtStartPar
this target builds a table of timing changes between two compilations; run
\sphinxcode{\sphinxupquote{make make\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}before}} to build the log of the “before” times,
and run \sphinxcode{\sphinxupquote{make make\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}after}} to build the log of the “after”
times. The table is printed on the command line, and stored in
\sphinxcode{\sphinxupquote{time\sphinxhyphen{}of\sphinxhyphen{}build\sphinxhyphen{}both.log}}. This target is most useful for profiling the
difference between two commits in a repository.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
This target requires \sphinxcode{\sphinxupquote{python}} to build the table.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{make\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}before}} and \sphinxcode{\sphinxupquote{make\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}after}} targets will
\sphinxstyleemphasis{append} to the timing log; if you want a fresh start, you must remove
the files \sphinxcode{\sphinxupquote{time\sphinxhyphen{}of\sphinxhyphen{}build\sphinxhyphen{}before.log}} and \sphinxcode{\sphinxupquote{time\sphinxhyphen{}of\sphinxhyphen{}build\sphinxhyphen{}after.log}} or run
\sphinxcode{\sphinxupquote{make cleanall}} \sphinxstyleemphasis{before} building either the “before” or “after”
targets.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The table will be sorted first by absolute time
differences rounded towards zero to a whole\sphinxhyphen{}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\sphinxhyphen{}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.

\sphinxAtStartPar
If you prefer a different sorting order, you can pass
\sphinxcode{\sphinxupquote{TIMING\_SORT\_BY=absolute}} to sort by the total time taken, or
\sphinxcode{\sphinxupquote{TIMING\_SORT\_BY=diff}} to sort by the signed difference in
time.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Just like \sphinxcode{\sphinxupquote{pretty\sphinxhyphen{}timed}}, this table defaults to using user
times.  Pass \sphinxcode{\sphinxupquote{TIMING\_REAL=1}} to \sphinxcode{\sphinxupquote{make}} on the command line
to show real times instead.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Just like \sphinxcode{\sphinxupquote{pretty\sphinxhyphen{}timed}}, passing \sphinxcode{\sphinxupquote{TIMING\_INCLUDE\_MEM=0}} to
\sphinxcode{\sphinxupquote{make}} will result in the tables not including peak memory
usage information.  Passing \sphinxcode{\sphinxupquote{TIMING\_SORT\_BY\_MEM=1}} to
\sphinxcode{\sphinxupquote{make}} will result in the tables be sorted by peak memory
usage rather than by the time taken.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For example, the output table from
\sphinxcode{\sphinxupquote{make print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}} may look like this:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
   After |  Peak Mem | File Name             |   Before |  Peak Mem ||    Change || Change (mem) |  \PYGZpc{} Change | \PYGZpc{} Change (mem)
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\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.43s | 394700 ko | Total Time / Peak Mem | 0m00.41s | 394648 ko || +0m00.01s ||        52 ko |    +4.87\PYGZpc{} |         +0.01\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{}\PYGZhy{}\PYGZhy{}\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 | 394700 ko | Fast.vo               | 0m00.02s |  56980 ko || +0m00.37s ||    337720 ko | +1850.00\PYGZpc{} |       +592.69\PYGZpc{}
0m00.04s |  56772 ko | Slow.vo               | 0m00.39s | 394648 ko || \PYGZhy{}0m00.35s ||   \PYGZhy{}337876 ko |   \PYGZhy{}89.74\PYGZpc{} |        \PYGZhy{}85.61\PYGZpc{}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{description}

\end{itemize}

\sphinxAtStartPar
The following targets and \sphinxcode{\sphinxupquote{Makefile}} variables allow collection of per\sphinxhyphen{}
line timing data:
\begin{itemize}
\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{TIMING=1}}}] \leavevmode
\sphinxAtStartPar
passing this variable will cause \sphinxcode{\sphinxupquote{make}} to use \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}time}} to
write to a \sphinxcode{\sphinxupquote{.v.timing}} file for each \sphinxcode{\sphinxupquote{.v}} file compiled, which contains
line\sphinxhyphen{}by\sphinxhyphen{}line timing information.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For example, running \sphinxcode{\sphinxupquote{make all TIMING=1}} may result in a file like this:

\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 {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}single\sphinxhyphen{}time\sphinxhyphen{}diff}}
\begin{quote}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
print\PYGZhy{}pretty\PYGZhy{}single\PYGZhy{}time\PYGZhy{}diff AFTER=path/to/file.v.after\PYGZhy{}timing BEFORE=path/to/file.v.before\PYGZhy{}timing
\end{sphinxVerbatim}

\sphinxAtStartPar
this target will make a sorted table of the per\sphinxhyphen{}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\sphinxhyphen{}of\sphinxhyphen{}build\sphinxhyphen{}pretty.log}}.
To generate the \sphinxcode{\sphinxupquote{.v.before\sphinxhyphen{}timing}} or \sphinxcode{\sphinxupquote{.v.after\sphinxhyphen{}timing}} files, you should
pass  \sphinxcode{\sphinxupquote{TIMING=before}} or \sphinxcode{\sphinxupquote{TIMING=after}} rather than \sphinxcode{\sphinxupquote{TIMING=1}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The sorting used here is the same as in the \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}} target.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
This target requires python to build the table.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
This target follows the same sorting order as the
\sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}} target, and supports the same
options for the \sphinxcode{\sphinxupquote{TIMING\_SORT\_BY}} variable.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
By default, two lines are only considered the same if the
character offsets and initial code strings are identical.  Passing
\sphinxcode{\sphinxupquote{TIMING\_FUZZ=N}} relaxes this constraint by allowing the
character locations to differ by up to \sphinxcode{\sphinxupquote{N}}, as long
as the total number of characters and initial code strings
continue to match.  This is useful when there are small changes
to a file, and you want to match later lines that have not
changed even though the character offsets have changed.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
By default the table picks up real times, under the assumption
that when comparing line\sphinxhyphen{}by\sphinxhyphen{}line, the real time is a more
accurate representation as it includes disk time and time spent
in the native compiler.  Passing \sphinxcode{\sphinxupquote{TIMING\_REAL=0}} to \sphinxcode{\sphinxupquote{make}}
will use user times rather than real times in the table.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
For example, running  \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}single\sphinxhyphen{}time\sphinxhyphen{}diff}} might give a table like this:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
After     | Code                                                | Before    || Change    | \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  | Total                                               | 0m04.17s  || \PYGZhy{}0m03.66s | \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 | Chars 069 \PYGZhy{} 162 [Definition\PYGZti{}foo0\PYGZti{}:=\PYGZti{}Eval\PYGZti{}comp\PYGZti{}i...] | 0m00.192s || \PYGZhy{}0m00.04s | \PYGZhy{}24.47\PYGZpc{}
0m00.126s | Chars 000 \PYGZhy{} 026 [Require\PYGZti{}Coq.ZArith.BinInt.]        | 0m00.143s || \PYGZhy{}0m00.01s | \PYGZhy{}11.88\PYGZpc{}
   N/A    | Chars 027 \PYGZhy{} 068 [Declare\PYGZti{}Reduction\PYGZti{}comp\PYGZti{}:=\PYGZti{}nati...] | 0m00.s    || +0m00.00s | N/A
0m00.s    | Chars 027 \PYGZhy{} 068 [Declare\PYGZti{}Reduction\PYGZti{}comp\PYGZti{}:=\PYGZti{}vm\PYGZus{}c...] |    N/A    || +0m00.00s | N/A
0m00.231s | Chars 163 \PYGZhy{} 208 [Definition\PYGZti{}foo1\PYGZti{}:=\PYGZti{}Eval\PYGZti{}comp\PYGZti{}i...] | 0m03.836s || \PYGZhy{}0m03.60s | \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
\sphinxAtStartPar
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\sphinxhyphen{}pretty\sphinxhyphen{}single\sphinxhyphen{}time\sphinxhyphen{}diff}} target; it depends on having already
made the corresponding \sphinxcode{\sphinxupquote{.v.before\sphinxhyphen{}timing}} and \sphinxcode{\sphinxupquote{.v.after\sphinxhyphen{}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\sphinxhyphen{}timing}} or \sphinxcode{\sphinxupquote{.v.after\sphinxhyphen{}timing}} files don’t exist.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
This target requires python to build the table.
\end{sphinxadmonition}

\end{description}

\end{itemize}


\subparagraph{Building a subset of the targets with \sphinxstyleliteralintitle{\sphinxupquote{\sphinxhyphen{}j}}}
\label{\detokenize{practical-tools/utilities:building-a-subset-of-the-targets-with-j}}
\sphinxAtStartPar
To build, say, two targets foo.vo and bar.vo in parallel one can use
\sphinxcode{\sphinxupquote{make only TGTS="foo.vo bar.vo" \sphinxhyphen{}j}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{make foo.vo bar.vo \sphinxhyphen{}j}} has a different meaning for the make
utility, in particular it may build a shared prerequisite twice.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
For users of coq\_makefile with version < 8.7
\begin{itemize}
\item {} 
\sphinxAtStartPar
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\sphinxhyphen{}all and post\sphinxhyphen{}all extension points.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{}extra\sphinxhyphen{}phony}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}extra}} are deprecated. To provide additional target
(\sphinxcode{\sphinxupquote{.PHONY}} or not) please use \sphinxcode{\sphinxupquote{CoqMakefile.local}}.

\end{itemize}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Due to limitations with the compilation chain, makefiles generated
by \sphinxcode{\sphinxupquote{coq\_makefile}} won't correctly compile OCaml plugins with OCaml
< 4.07.0 when using more than one job (\sphinxcode{\sphinxupquote{\sphinxhyphen{}j N}} for \sphinxcode{\sphinxupquote{N > 1}}).
\end{sphinxadmonition}


\subparagraph{Precompiling for \sphinxstyleliteralintitle{\sphinxupquote{native\_compute}}}
\label{\detokenize{practical-tools/utilities:precompiling-for-native-compute}}
\sphinxAtStartPar
To compile files for \sphinxcode{\sphinxupquote{native\_compute}}, one can use the
\sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler yes}} option of Coq, for instance by putting the
following in a {\hyperref[\detokenize{practical-tools/utilities:coqmakefilelocal}]{\sphinxcrossref{\DUrole{std,std-ref}{CoqMakefile.local}}}} file:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
COQEXTRAFLAGS += \PYGZhy{}native\PYGZhy{}compiler yes
\end{sphinxVerbatim}

\sphinxAtStartPar
The generated \sphinxcode{\sphinxupquote{CoqMakefile}} installation target will then take care
of installing the extra \sphinxcode{\sphinxupquote{.coq\sphinxhyphen{}native}} directories.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
As an alternative to modifying any file, one can set the
environment variable when calling \sphinxcode{\sphinxupquote{make}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
COQEXTRAFLAGS=\PYGZdq{}\PYGZhy{}native\PYGZhy{}compiler yes\PYGZdq{} make
\end{sphinxVerbatim}

\sphinxAtStartPar
This can be useful when files cannot be modified, for instance when
installing via OPAM a package built with \sphinxcode{\sphinxupquote{coq\_makefile}}:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
COQEXTRAFLAGS=\PYGZdq{}\PYGZhy{}native\PYGZhy{}compiler yes\PYGZdq{} opam install coq\PYGZhy{}package
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
This requires all dependencies to be themselves compiled with
\sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler yes}}.
\end{sphinxadmonition}


\paragraph{Building a Coq project with Dune}
\label{\detokenize{practical-tools/utilities:building-a-coq-project-with-dune}}
\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
Dune's Coq support is still experimental; we strongly recommend
using Dune 2.3 or later.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The canonical documentation for the Coq Dune extension is
maintained upstream; please refer to the \sphinxhref{https://dune.readthedocs.io/}{Dune manual}%
\begin{footnote}[64]\sphinxAtStartFootnote
\sphinxnolinkurl{https://dune.readthedocs.io/}
%
\end{footnote} for up\sphinxhyphen{}to\sphinxhyphen{}date information. This
documentation is up to date for Dune 2.3.
\end{sphinxadmonition}

\sphinxAtStartPar
Building a Coq project with Dune requires setting up a Dune project
for your files. This involves adding a \sphinxcode{\sphinxupquote{dune\sphinxhyphen{}project}} and
\sphinxcode{\sphinxupquote{pkg.opam}} file to the root (\sphinxcode{\sphinxupquote{pkg.opam}} can be empty or generated
by Dune itself), and then providing \sphinxcode{\sphinxupquote{dune}} files in the directories
your \sphinxcode{\sphinxupquote{.v}} files are placed. For the experimental version "0.1" of
the Coq Dune language, Coq library stanzas look like:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{(}\PYG{n+nf}{coq}\PYG{o}{.}\PYG{n+nv}{theory}
 \PYG{p}{(}\PYG{n+nf}{name} \PYG{n+nv}{\PYGZlt{}module\PYGZus{}prefix\PYGZgt{}}\PYG{p}{)}
 \PYG{p}{(}\PYG{n+nf}{package} \PYG{n+nv}{\PYGZlt{}opam\PYGZus{}package\PYGZgt{}}\PYG{p}{)}
 \PYG{p}{(}\PYG{n+nf}{synopsis} \PYG{n+nv}{\PYGZlt{}text\PYGZgt{}}\PYG{p}{)}
 \PYG{p}{(}\PYG{n+nf}{modules} \PYG{n+nv}{\PYGZlt{}ordered\PYGZus{}set\PYGZus{}lang\PYGZgt{}}\PYG{p}{)}
 \PYG{p}{(}\PYG{n+nf}{libraries} \PYG{n+nv}{\PYGZlt{}ocaml\PYGZus{}libraries\PYGZgt{}}\PYG{p}{)}
 \PYG{p}{(}\PYG{n+nf}{flags} \PYG{n+nv}{\PYGZlt{}coq\PYGZus{}flags\PYGZgt{}}\PYG{p}{)}\PYG{p}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
This stanza will build all \sphinxcode{\sphinxupquote{.v}} files in the given directory, wrapping
the library under \sphinxcode{\sphinxupquote{<module\_prefix>}}. If you declare an
\sphinxcode{\sphinxupquote{<opam\_package>}}, an \sphinxcode{\sphinxupquote{.install}} file for the library will be
generated; the optional \sphinxcode{\sphinxupquote{(modules <ordered\_set\_lang>)}} field allows
you to filter the list of modules, and \sphinxcode{\sphinxupquote{(libraries
<ocaml\_libraries>)}} allows the Coq theory depend on ML plugins. For
the moment, Dune relies on Coq's standard mechanisms (such as
\sphinxcode{\sphinxupquote{COQPATH}}) to locate installed Coq libraries.

\sphinxAtStartPar
By default Dune will skip \sphinxcode{\sphinxupquote{.v}} files present in subdirectories. In
order to enable the usual recursive organization of Coq projects add

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{(}\PYG{n+nf}{include\PYGZus{}subdirs} \PYG{n+nv}{qualified}\PYG{p}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
to you \sphinxcode{\sphinxupquote{dune}} file.

\sphinxAtStartPar
Once your project is set up, \sphinxcode{\sphinxupquote{dune build}} will generate the
\sphinxcode{\sphinxupquote{pkg.install}} files and all the files necessary for the installation
of your project.

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
A typical stanza for a Coq plugin is split into two parts. An OCaml build directive, which is standard Dune:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{(}\PYG{n+nf}{library}
 \PYG{p}{(}\PYG{n+nf}{name} \PYG{n+nv}{equations\PYGZus{}plugin}\PYG{p}{)}
 \PYG{p}{(}\PYG{n+nf}{public\PYGZus{}name} \PYG{n+nv}{equations}\PYG{o}{.}\PYG{n+nv}{plugin}\PYG{p}{)}
 \PYG{p}{(}\PYG{n+nf}{flags} \PYG{n+nv}{:standard} \PYG{n+nv}{\PYGZhy{}warn\PYGZhy{}error} \PYG{l+m+mi}{\PYGZhy{}3}\PYG{l+m+mi}{\PYGZhy{}9}\PYG{l+m+mi}{\PYGZhy{}27}\PYG{l+m+mi}{\PYGZhy{}32}\PYG{l+m+mi}{\PYGZhy{}33}\PYG{l+m+mi}{\PYGZhy{}50}\PYG{p}{)}
 \PYG{p}{(}\PYG{n+nf}{libraries} \PYG{n+nv}{coq}\PYG{o}{.}\PYG{n+nv}{plugins}\PYG{o}{.}\PYG{n+nv}{cc} \PYG{n+nv}{coq}\PYG{o}{.}\PYG{n+nv}{plugins}\PYG{o}{.}\PYG{n+nv}{extraction}\PYG{p}{)}\PYG{p}{)}

\PYG{p}{(}\PYG{n+nf}{coq}\PYG{o}{.}\PYG{n+nv}{pp} \PYG{p}{(}\PYG{n+nf}{modules} \PYG{n+nv}{g\PYGZus{}equations}\PYG{p}{)}\PYG{p}{)}
\end{sphinxVerbatim}

\sphinxAtStartPar
And a Coq\sphinxhyphen{}specific part that depends on it via the \sphinxcode{\sphinxupquote{libraries}} field:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(coq.theory
 (name Equations) ; \PYGZhy{}R flag
 (package equations)
 (synopsis \PYGZdq{}Equations Plugin\PYGZdq{})
 (libraries coq.plugins.extraction equations.plugin)
 (modules :standard \PYGZbs{} IdDec NoCycle)) ; exclude some modules that don\PYGZsq{}t build

(include\PYGZus{}subdirs qualified)
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Computing Module dependencies}
\label{\detokenize{practical-tools/utilities:computing-module-dependencies}}\label{\detokenize{practical-tools/utilities:coqdep}}
\sphinxAtStartPar
In order to compute module dependencies (to be used by \sphinxcode{\sphinxupquote{make}} or
\sphinxcode{\sphinxupquote{dune}}), Coq provides the \sphinxcode{\sphinxupquote{coqdep}} tool.

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{coqdep}} computes inter\sphinxhyphen{}module dependencies for Coq
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.

\sphinxAtStartPar
Dependencies of 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}}.

\sphinxAtStartPar
See the man page of \sphinxcode{\sphinxupquote{coqdep}} for more details and options.

\sphinxAtStartPar
Both Dune and \sphinxcode{\sphinxupquote{coq\_makefile}} use \sphinxcode{\sphinxupquote{coqdep}} to compute the
dependencies among the files part of a Coq project.


\subsubsection{Split compilation of native computation files}
\label{\detokenize{practical-tools/utilities:split-compilation-of-native-computation-files}}\label{\detokenize{practical-tools/utilities:coqnative}}
\sphinxAtStartPar
Coq features a {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} tactic to provide fast computation in the
kernel. This process performs compilation of Coq terms to OCaml programs using
the OCaml compiler, which may cause an important overhead. Hence native
compilation is an opt\sphinxhyphen{}in configure flag.

\sphinxAtStartPar
When native compilation is activated, Coq generates the compiled files upfront,
i.e. during the \sphinxcode{\sphinxupquote{coqc}} invocation on the corresponding \sphinxcode{\sphinxupquote{.v}} file. This is
impractical because it means one must chose in advance whether they will use
a native\sphinxhyphen{}capable Coq installation. In particular, activating native compilation
forces the recompilation of the whole Coq installation. See
{\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{command line options}}}} for more details.

\sphinxAtStartPar
Starting from Coq 8.14, a new binary \sphinxcode{\sphinxupquote{coqnative}} is available. It allows
performing split native compilation by generating the native compute files out
of the compiled \sphinxcode{\sphinxupquote{.vo}} file rather than out of the source \sphinxcode{\sphinxupquote{.v}} file.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{coqnative}} command takes a name \sphinxstyleemphasis{file.vo} as argument and tries to
perform native compilation on it. It assumes that the Coq libraries on which
\sphinxstyleemphasis{file.vo} depends have been first compiled to their native files, and will fail
otherwise. It accepts the \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}I}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}nI}} arguments with the
same semantics as if the native compilation process had been performed through
\sphinxcode{\sphinxupquote{coqc}}. In particular, it means that:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{}R}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}} are equivalent

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{}I}} is a no\sphinxhyphen{}op that is accepted only for scripting convenience

\end{itemize}


\subsubsection{Embedded Coq phrases inside LaTeX documents}
\label{\detokenize{practical-tools/utilities:embedded-coq-phrases-inside-latex-documents}}
\sphinxAtStartPar
When writing documentation about a proof development, one may want
to insert 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 Coq phrases embedded in \DUrole{smallcaps}{LaTeX} files: the \sphinxcode{\sphinxupquote{coq\sphinxhyphen{}tex}}
filter. This filter extracts Coq phrases embedded in \DUrole{smallcaps}{LaTeX} files,
evaluates them, and insert the outcome of the evaluation after each
phrase.

\sphinxAtStartPar
Starting with a file \sphinxcode{\sphinxupquote{file.tex}} containing Coq phrases, the \sphinxcode{\sphinxupquote{coq\sphinxhyphen{}tex}}
filter produces a file named \sphinxcode{\sphinxupquote{file.v.tex}} with the Coq outcome.

\sphinxAtStartPar
There are options to produce the Coq parts in smaller font, italic,
between horizontal rules, etc. See the man page of \sphinxcode{\sphinxupquote{coq\sphinxhyphen{}tex}} for more
details.


\subsubsection{Man pages}
\label{\detokenize{practical-tools/utilities:man-pages}}
\sphinxAtStartPar
There are man pages for the commands \sphinxcode{\sphinxupquote{coqdep}} and \sphinxcode{\sphinxupquote{coq\sphinxhyphen{}tex}}. Man
pages are installed at installation time (see installation
instructions in file \sphinxcode{\sphinxupquote{INSTALL}}, step 6).

\index{coqdoc@\spxentry{coqdoc}}\ignorespaces 

\subsection{Documenting Coq files with coqdoc}
\label{\detokenize{using/tools/coqdoc:documenting-coq-files-with-coqdoc}}\label{\detokenize{using/tools/coqdoc:coqdoc}}\label{\detokenize{using/tools/coqdoc:index-0}}\label{\detokenize{using/tools/coqdoc::doc}}
\sphinxAtStartPar
coqdoc is a documentation tool for the proof assistant Coq, similar to
\sphinxcode{\sphinxupquote{javadoc}} or \sphinxcode{\sphinxupquote{ocamldoc}}. The task of coqdoc is
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
to produce a nice \DUrole{smallcaps}{LaTeX} and/or HTML document from Coq source files,
readable for a human and not only for the proof assistant;

\item {} 
\sphinxAtStartPar
to help the user navigate his own (or third\sphinxhyphen{}party) sources.

\end{enumerate}


\subsubsection{Principles}
\label{\detokenize{using/tools/coqdoc:principles}}
\sphinxAtStartPar
Documentation is inserted into Coq files as \sphinxstyleemphasis{special comments}. Thus
your files will compile as usual, whether you use coqdoc or not. coqdoc
presupposes that the given Coq files are well\sphinxhyphen{}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\sphinxhyphen{}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{using/tools/coqdoc:coq-material-inside-documentation}}
\sphinxAtStartPar
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{let id := fun {[}T : Type{]} (x : t) => x in id 0}}
by writing  \sphinxcode{\sphinxupquote{{[}let id := fun {[}T : Type{]} (x : t) => x in id 0{]}}}).
Inside quotations, the code is pretty\sphinxhyphen{}printed the same way as in code parts.

\sphinxAtStartPar
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\sphinxhyphen{}printing.}
\label{\detokenize{using/tools/coqdoc:pretty-printing}}
\sphinxAtStartPar
coqdoc uses different faces for identifiers and keywords. The pretty\sphinxhyphen{}
printing of Coq tokens (identifiers or symbols) can be controlled
using one of the following commands:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** printing  *token* \PYGZpc{}...LATEX...\PYGZpc{} \PYGZsh{}...html...\PYGZsh{} *)
\end{sphinxVerbatim}

\sphinxAtStartPar
or

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** printing  *token* \PYGZdl{}...LATEX math...\PYGZdl{} \PYGZsh{}...html...\PYGZsh{} *)
\end{sphinxVerbatim}

\sphinxAtStartPar
It gives the \DUrole{smallcaps}{LaTeX} and HTML texts to be produced for the given Coq
token. Either the \DUrole{smallcaps}{LaTeX} or the HTML rule may be omitted, causing the
default pretty\sphinxhyphen{}printing to be used for this token.

\sphinxAtStartPar
The printing for one token can be removed with

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** remove printing  *token* *)
\end{sphinxVerbatim}

\sphinxAtStartPar
Initially, the pretty\sphinxhyphen{}printing table contains the following mapping:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|T|T|T|T|}
\hline

\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{}>}}
&
\sphinxAtStartPar
→
&&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{<\sphinxhyphen{}}}
&
\sphinxAtStartPar
←
&&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{*}}
&
\sphinxAtStartPar
×
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{<=}}
&
\sphinxAtStartPar
≤
&&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{>=}}
&
\sphinxAtStartPar
≥
&&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{=>}}
&
\sphinxAtStartPar
⇒
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{<>}}
&
\sphinxAtStartPar
≠
&&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{<\sphinxhyphen{}>}}
&
\sphinxAtStartPar
↔
&&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{|\sphinxhyphen{}}}
&
\sphinxAtStartPar
⊢
\\
\hline
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\textbackslash{}/}}
&
\sphinxAtStartPar
∨
&&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{/\textbackslash{}}}
&
\sphinxAtStartPar
∧
&&
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\textasciitilde{}}}
&
\sphinxAtStartPar
¬
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\sphinxAtStartPar
Any of these can be overwritten or suppressed using the printing
commands.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
The recognition of tokens is done by a (\sphinxcode{\sphinxupquote{ocaml}}) lex
automaton and thus applies the longest\sphinxhyphen{}match rule. For instance, \sphinxcode{\sphinxupquote{\sphinxhyphen{}>\textasciitilde{}}}
is recognized as a single token, where Coq sees two tokens. It is the
responsibility of the user to insert space between tokens \sphinxstyleemphasis{or} to give
pretty\sphinxhyphen{}printing rules for the possible combinations, e.g.

\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{using/tools/coqdoc:sections}}
\sphinxAtStartPar
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}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** * Well\PYGZhy{}founded relations

    In this section, we introduce...  *)
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Lists.}
\label{\detokenize{using/tools/coqdoc:lists}}
\sphinxAtStartPar
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\sphinxhyphen{}space character on its line (so, in particular, a
list can not begin on the first line of a comment \sphinxhyphen{} start it on the
second line instead).

\begin{sphinxadmonition}{note}{Example}

\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{using/tools/coqdoc:rules}}
\sphinxAtStartPar
More than 4 leading dashes produce a horizontal rule.


\paragraph{Emphasis.}
\label{\detokenize{using/tools/coqdoc:emphasis}}
\sphinxAtStartPar
Text can be italicized by enclosing it in underscores. A non\sphinxhyphen{}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.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
This sentence contains some \PYGZus{}emphasized text\PYGZus{}.
\end{sphinxVerbatim}


\paragraph{Escaping to LaTeX and HTML.}
\label{\detokenize{using/tools/coqdoc:escaping-to-latex-and-html}}
\sphinxAtStartPar
Pure \DUrole{smallcaps}{LaTeX} or HTML material can be inserted using the following
escape sequences:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\$...LATEX stuff...\$}} inserts some \DUrole{smallcaps}{LaTeX} material in math mode.
Simply discarded in HTML output.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\%...LATEX stuff...\%}} inserts some \DUrole{smallcaps}{LaTeX} material. Simply
discarded in HTML output.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\#...HTML stuff...\#}} inserts some HTML material. Simply discarded in
\DUrole{smallcaps}{LaTeX} output.

\end{itemize}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
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{using/tools/coqdoc:verbatim}}
\sphinxAtStartPar
Verbatim material is introduced by a leading \sphinxcode{\sphinxupquote{<<}} and closed by \sphinxcode{\sphinxupquote{>>}}
at the beginning of a line.

\begin{sphinxadmonition}{note}{Example}

\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}

\sphinxAtStartPar
Verbatim material on a single line is also possible (assuming that
\sphinxcode{\sphinxupquote{>>}} is not part of the text to be presented as verbatim).

\begin{sphinxadmonition}{note}{Example}

\begin{sphinxVerbatim}[commandchars=\\\{\}]
Here is the corresponding caml expression: \PYGZlt{}\PYGZlt{} fact (n\PYGZhy{}1) \PYGZgt{}\PYGZgt{}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Hyperlinks}
\label{\detokenize{using/tools/coqdoc:hyperlinks}}
\sphinxAtStartPar
Hyperlinks can be inserted into the HTML output, so that any
identifier is linked to the place of its definition.

\sphinxAtStartPar
\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{\sphinxhyphen{}\sphinxhyphen{}dump\sphinxhyphen{}glob
file}}. Take care of erasing this global file, if any, when starting
the whole compilation process.

\sphinxAtStartPar
Then invoke coqdoc or \sphinxcode{\sphinxupquote{coqdoc \sphinxhyphen{}\sphinxhyphen{}glob\sphinxhyphen{}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).

\sphinxAtStartPar
Identifiers from the 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{\sphinxhyphen{}\sphinxhyphen{}no\sphinxhyphen{}externals}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}coqlib}}; see below.


\paragraph{Hiding / Showing parts of the source}
\label{\detokenize{using/tools/coqdoc:hiding-showing-parts-of-the-source}}\label{\detokenize{using/tools/coqdoc:coqdoc-hide-show}}
\sphinxAtStartPar
Some parts of the source can be hidden using command line options \sphinxcode{\sphinxupquote{\sphinxhyphen{}g}}
and \sphinxcode{\sphinxupquote{\sphinxhyphen{}l}} (see below), or using such comments:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(* begin hide *)
 *some Coq material*
(* end hide *)
\end{sphinxVerbatim}

\sphinxAtStartPar
Conversely, some parts of the source which would be hidden can be
shown using such comments:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(* begin show *)
 *some Coq material*
(* end show *)
\end{sphinxVerbatim}

\sphinxAtStartPar
The latter cannot be used around some inner parts of a proof, but can
be used around a whole proof.

\sphinxAtStartPar
Lastly, it is possible to adopt a middle\sphinxhyphen{}ground approach when the
desired output is HTML, where a given snippet of Coq material is
hidden by default, but can be made visible with user interaction.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(* begin details *)
 *some Coq material*
(* end details *)
\end{sphinxVerbatim}

\sphinxAtStartPar
There is also an alternative syntax available.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(* begin details : Some summary describing the snippet *)
 *some Coq material*
(* end details *)
\end{sphinxVerbatim}


\subsubsection{Usage}
\label{\detokenize{using/tools/coqdoc:usage}}
\sphinxAtStartPar
coqdoc is invoked on a shell command line as follows:
\sphinxcode{\sphinxupquote{coqdoc <options and files>}}.
Any command line argument which is not an option is considered to be a
file (even if it starts with a \sphinxcode{\sphinxupquote{\sphinxhyphen{}}}). 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
\sphinxAtStartPar
This is the default output format. One HTML file is created for
each Coq file given on the command line, together with a file
\sphinxcode{\sphinxupquote{index.html}} (unless \sphinxcode{\sphinxupquote{option\sphinxhyphen{}no\sphinxhyphen{}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
\sphinxAtStartPar
A single \DUrole{smallcaps}{LaTeX} file is created, on standard
output. It can be redirected to a file using the option \sphinxcode{\sphinxupquote{\sphinxhyphen{}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{\sphinxhyphen{}dvi}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}ps}} respectively.

\item[{TEXmacs output}] \leavevmode
\sphinxAtStartPar
To translate the input files to TEXmacs format,
to be used by the TEXmacs Coq interface.

\end{description}\end{quote}


\paragraph{Command line options}
\label{\detokenize{using/tools/coqdoc:command-line-options}}
\sphinxAtStartPar
\sphinxstylestrong{Overall options}
\begin{quote}
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}\sphinxhyphen{}HTML}] \leavevmode
\sphinxAtStartPar
Select a HTML output.

\item[{\sphinxhyphen{}\sphinxhyphen{}\DUrole{smallcaps}{LaTeX}}] \leavevmode
\sphinxAtStartPar
Select a \DUrole{smallcaps}{LaTeX} output.

\item[{\sphinxhyphen{}\sphinxhyphen{}dvi}] \leavevmode
\sphinxAtStartPar
Select a DVI output.

\item[{\sphinxhyphen{}\sphinxhyphen{}ps}] \leavevmode
\sphinxAtStartPar
Select a PostScript output.

\item[{\sphinxhyphen{}\sphinxhyphen{}texmacs}] \leavevmode
\sphinxAtStartPar
Select a TEXmacs output.

\item[{\sphinxhyphen{}\sphinxhyphen{}stdout}] \leavevmode
\sphinxAtStartPar
Write output to stdout.

\item[{\sphinxhyphen{}o file, \sphinxhyphen{}\sphinxhyphen{}output file}] \leavevmode
\sphinxAtStartPar
Redirect the output into the file ‘file’
(meaningless with \sphinxcode{\sphinxupquote{\sphinxhyphen{}html}}).

\item[{\sphinxhyphen{}d dir, \sphinxhyphen{}\sphinxhyphen{}directory dir}] \leavevmode
\sphinxAtStartPar
Output files into directory ‘dir’ instead of
the current directory (option \sphinxcode{\sphinxupquote{\sphinxhyphen{}d}} does not change the filename specified
with the option \sphinxcode{\sphinxupquote{\sphinxhyphen{}o}}, if any).

\item[{\sphinxhyphen{}\sphinxhyphen{}body\sphinxhyphen{}only}] \leavevmode
\sphinxAtStartPar
Suppress the header and trailer of the final document.
Thus, you can insert the resulting document into a larger one.

\item[{\sphinxhyphen{}p string, \sphinxhyphen{}\sphinxhyphen{}preamble string}] \leavevmode
\sphinxAtStartPar
Insert some material in the \DUrole{smallcaps}{LaTeX}
preamble, right before \sphinxcode{\sphinxupquote{\textbackslash{}begin\{document\}}} (meaningless with \sphinxcode{\sphinxupquote{\sphinxhyphen{}html}}).

\item[{\sphinxhyphen{}\sphinxhyphen{}vernac\sphinxhyphen{}file file,\sphinxhyphen{}\sphinxhyphen{}tex\sphinxhyphen{}file file}] \leavevmode
\sphinxAtStartPar
Considers the file ‘file’
respectively as a \sphinxcode{\sphinxupquote{.v}} (or \sphinxcode{\sphinxupquote{.g}}) file or a \sphinxcode{\sphinxupquote{.tex}} file.

\item[{\sphinxhyphen{}\sphinxhyphen{}files\sphinxhyphen{}from file}] \leavevmode
\sphinxAtStartPar
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[{\sphinxhyphen{}q, \sphinxhyphen{}\sphinxhyphen{}quiet}] \leavevmode
\sphinxAtStartPar
Be quiet. Do not print anything except errors.

\item[{\sphinxhyphen{}h, \sphinxhyphen{}\sphinxhyphen{}help}] \leavevmode
\sphinxAtStartPar
Give a short summary of the options and exit.

\item[{\sphinxhyphen{}v, \sphinxhyphen{}\sphinxhyphen{}version}] \leavevmode
\sphinxAtStartPar
Print the version and exit.

\end{description}\end{quote}
\end{quote}

\sphinxAtStartPar
\sphinxstylestrong{Index options}
\begin{quote}

\sphinxAtStartPar
The default behavior is to build an index, for the HTML output only,
into \sphinxcode{\sphinxupquote{index.html}}.
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}\sphinxhyphen{}no\sphinxhyphen{}index}] \leavevmode
\sphinxAtStartPar
Do not output the index.

\item[{\sphinxhyphen{}\sphinxhyphen{}multi\sphinxhyphen{}index}] \leavevmode
\sphinxAtStartPar
Generate one page for each category and each letter in
the index, together with a top page \sphinxcode{\sphinxupquote{index.html}}.

\item[{\sphinxhyphen{}\sphinxhyphen{}index string}] \leavevmode
\sphinxAtStartPar
Make the filename of the index string instead of
“index”. Useful since “index.html” is special.

\end{description}\end{quote}
\end{quote}

\sphinxAtStartPar
\sphinxstylestrong{Table of contents option}
\begin{quote}
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}toc, \sphinxhyphen{}\sphinxhyphen{}table\sphinxhyphen{}of\sphinxhyphen{}contents}] \leavevmode
\sphinxAtStartPar
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[{\sphinxhyphen{}\sphinxhyphen{}toc\sphinxhyphen{}depth int}] \leavevmode
\sphinxAtStartPar
Only include headers up to depth \sphinxcode{\sphinxupquote{int}} in the table of
contents.

\end{description}\end{quote}
\end{quote}

\sphinxAtStartPar
\sphinxstylestrong{Hyperlink options}
\begin{quote}
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}\sphinxhyphen{}glob\sphinxhyphen{}from file}] \leavevmode
\sphinxAtStartPar
Make references using Coq globalizations from file
file. (Such globalizations are obtained with Coq option \sphinxcode{\sphinxupquote{\sphinxhyphen{}dump\sphinxhyphen{}glob}}).

\item[{\sphinxhyphen{}\sphinxhyphen{}no\sphinxhyphen{}externals}] \leavevmode
\sphinxAtStartPar
Do not insert links to the Coq standard library.

\item[{\sphinxhyphen{}\sphinxhyphen{}external url coqdir}] \leavevmode
\sphinxAtStartPar
Use given URL for linking references whose
name starts with prefix \sphinxcode{\sphinxupquote{coqdir}}.

\item[{\sphinxhyphen{}\sphinxhyphen{}coqlib url}] \leavevmode
\sphinxAtStartPar
Set base URL for the Coq standard library (default is
\sphinxurl{http://coq.inria.fr/library/}). This is equivalent to \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}external url
Coq}}.

\item[{\sphinxhyphen{}R dir coqdir}] \leavevmode
\sphinxAtStartPar
Recursively map physical directory dir to Coq logical
directory  \sphinxcode{\sphinxupquote{coqdir}} (similarly to Coq option \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}}).

\item[{\sphinxhyphen{}Q dir coqdir}] \leavevmode
\sphinxAtStartPar
Map physical directory dir to Coq logical
directory  \sphinxcode{\sphinxupquote{coqdir}} (similarly to Coq option \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}}).

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
options \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}} only have
effect on the files \sphinxstyleemphasis{following} them on the command line, so you will
probably need to put this option first.
\end{sphinxadmonition}

\end{description}\end{quote}
\end{quote}

\sphinxAtStartPar
\sphinxstylestrong{Title options}
\begin{quote}
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}s , \sphinxhyphen{}\sphinxhyphen{}short}] \leavevmode
\sphinxAtStartPar
Do not insert titles for the files. The default
behavior is to insert a title like “Library Foo” for each file.

\item[{\sphinxhyphen{}\sphinxhyphen{}lib\sphinxhyphen{}name string}] \leavevmode
\sphinxAtStartPar
Print “string Foo” instead of “Library Foo” in
titles. For example “Chapter” and “Module” are reasonable choices.

\item[{\sphinxhyphen{}\sphinxhyphen{}no\sphinxhyphen{}lib\sphinxhyphen{}name}] \leavevmode
\sphinxAtStartPar
Print just “Foo” instead of “Library Foo” in titles.

\item[{\sphinxhyphen{}\sphinxhyphen{}lib\sphinxhyphen{}subtitles}] \leavevmode
\sphinxAtStartPar
Look for library subtitles. When enabled, the
beginning of each file is checked for a comment of the form:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** * ModuleName : text *)
\end{sphinxVerbatim}

\sphinxAtStartPar
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[{\sphinxhyphen{}t string, \sphinxhyphen{}\sphinxhyphen{}title string}] \leavevmode
\sphinxAtStartPar
Set the document title.

\end{description}\end{quote}
\end{quote}

\sphinxAtStartPar
\sphinxstylestrong{Contents options}
\begin{quote}
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}g, \sphinxhyphen{}\sphinxhyphen{}gallina}] \leavevmode
\sphinxAtStartPar
Do not print proofs.

\item[{\sphinxhyphen{}l, \sphinxhyphen{}\sphinxhyphen{}light}] \leavevmode
\sphinxAtStartPar
Light mode. Suppress proofs (as with \sphinxcode{\sphinxupquote{\sphinxhyphen{}g}}) and the following commands:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{[}Recursive{]} Tactic Definition

\item {} 
\sphinxAtStartPar
Hint / Hints

\item {} 
\sphinxAtStartPar
Require

\item {} 
\sphinxAtStartPar
Transparent / Opaque

\item {} 
\sphinxAtStartPar
Implicit Argument / Implicits

\item {} 
\sphinxAtStartPar
Section / Variable / Hypothesis / End

\end{itemize}

\sphinxAtStartPar
The behavior of options \sphinxcode{\sphinxupquote{\sphinxhyphen{}g}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}l}} can be locally overridden using the
\sphinxcode{\sphinxupquote{(* begin show *) … (* end show *)}} environment (see above).

\sphinxAtStartPar
There are a few options that control the parsing of comments:

\item[{\sphinxhyphen{}\sphinxhyphen{}parse\sphinxhyphen{}comments}] \leavevmode
\sphinxAtStartPar
Parse regular comments delimited by \sphinxcode{\sphinxupquote{(*}} and \sphinxcode{\sphinxupquote{*)}} as
well. They are typeset inline.

\item[{\sphinxhyphen{}\sphinxhyphen{}plain\sphinxhyphen{}comments}] \leavevmode
\sphinxAtStartPar
Do not interpret comments, simply copy them as
plain\sphinxhyphen{}text.

\item[{\sphinxhyphen{}\sphinxhyphen{}interpolate}] \leavevmode
\sphinxAtStartPar
Use the globalization information to typeset
identifiers appearing in Coq escapings inside comments.

\end{description}\end{quote}
\end{quote}

\sphinxAtStartPar
\sphinxstylestrong{Language options}
\begin{quote}

\sphinxAtStartPar
The default behavior is to assume ASCII 7 bit input files.
\begin{quote}\begin{description}
\item[{\sphinxhyphen{}latin1, \sphinxhyphen{}\sphinxhyphen{}latin1}] \leavevmode
\sphinxAtStartPar
Select ISO\sphinxhyphen{}8859\sphinxhyphen{}1 input files. It is equivalent to
\sphinxhyphen{}\sphinxhyphen{}inputenc latin1 \sphinxhyphen{}\sphinxhyphen{}charset iso\sphinxhyphen{}8859\sphinxhyphen{}1.

\item[{\sphinxhyphen{}utf8, \sphinxhyphen{}\sphinxhyphen{}utf8}] \leavevmode
\sphinxAtStartPar
Set \sphinxhyphen{}\sphinxhyphen{}inputenc utf8x for \DUrole{smallcaps}{LaTeX} output and\sphinxhyphen{}\sphinxhyphen{}charset
utf\sphinxhyphen{}8 for HTML output. Also use Unicode replacements for a couple of
standard plain ASCII notations such as → for \sphinxcode{\sphinxupquote{\sphinxhyphen{}>}} and ∀ for \sphinxcode{\sphinxupquote{forall}}. \DUrole{smallcaps}{LaTeX}
UTF\sphinxhyphen{}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\sphinxhyphen{}interpretation\}}}. Packages
and declarations can be added with option \sphinxcode{\sphinxupquote{\sphinxhyphen{}p}}.

\item[{\sphinxhyphen{}\sphinxhyphen{}inputenc string}] \leavevmode
\sphinxAtStartPar
Give a \DUrole{smallcaps}{LaTeX} input encoding, as an option to \DUrole{smallcaps}{LaTeX}
package \sphinxcode{\sphinxupquote{inputenc}}.

\item[{\sphinxhyphen{}\sphinxhyphen{}charset string}] \leavevmode
\sphinxAtStartPar
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{using/tools/coqdoc:the-coqdoc-latex-style-file}}
\sphinxAtStartPar
In case you choose to produce a document without the default \DUrole{smallcaps}{LaTeX}
preamble (by using option \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}no\sphinxhyphen{}preamble}}), then you must insert into
your own preamble the command

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZbs{}usepackage\PYGZob{}coqdoc\PYGZcb{}
\end{sphinxVerbatim}

\sphinxAtStartPar
The package optionally takes the argument \sphinxcode{\sphinxupquote{{[}color{]}}} to typeset
identifiers with colors (this requires the \sphinxcode{\sphinxupquote{xcolor}} package).

\sphinxAtStartPar
Then you may alter the rendering of the document by redefining some
macros:
\begin{quote}\begin{description}
\item[{coqdockw, coqdocid, …}] \leavevmode
\sphinxAtStartPar
The one\sphinxhyphen{}argument macros for typesetting
keywords and identifiers. Defaults are sans\sphinxhyphen{}serif for keywords and
italic for identifiers.For example, if you would like a slanted font
for keywords, you may insert

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZbs{}renewcommand\PYGZob{}\PYGZbs{}coqdockw\PYGZcb{}[1]\PYGZob{}\PYGZbs{}textsl\PYGZob{}\PYGZsh{}1\PYGZcb{}\PYGZcb{}
\end{sphinxVerbatim}

\sphinxAtStartPar
anywhere between \sphinxcode{\sphinxupquote{\textbackslash{}usepackage\{coqdoc\}}} and \sphinxcode{\sphinxupquote{\textbackslash{}begin\{document\}}}.

\item[{coqdocmodule}] \leavevmode
\sphinxAtStartPar
One\sphinxhyphen{}argument macro for typesetting the title of a \sphinxcode{\sphinxupquote{.v}}
file. Default is

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZbs{}newcommand\PYGZob{}\PYGZbs{}coqdocmodule\PYGZcb{}[1]\PYGZob{}\PYGZbs{}section*\PYGZob{}Module \PYGZsh{}1\PYGZcb{}\PYGZcb{}
\end{sphinxVerbatim}

\sphinxAtStartPar
and you may redefine it using \sphinxcode{\sphinxupquote{\textbackslash{}renewcommand}}.

\end{description}\end{quote}


\subsection{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}}
\sphinxAtStartPar
The Coq Integrated Development Environment is a graphical tool, to be
used as a user\sphinxhyphen{}friendly replacement to \sphinxcode{\sphinxupquote{coqtop}}. Its main purpose is to
allow the user to navigate forward and backward into a Coq
file, executing corresponding commands or undoing them respectively.

\sphinxAtStartPar
CoqIDE is run by typing the command \sphinxcode{\sphinxupquote{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, \sphinxcode{\sphinxupquote{coqide}} accepts the same
options as \sphinxcode{\sphinxupquote{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 CoqIDE being ignored.

\phantomsection\label{\detokenize{practical-tools/coqide:coqide-mainscreen}}\begin{quote}

\noindent\sphinxincludegraphics{{coqide}.png}
\end{quote}

\sphinxAtStartPar
A sample CoqIDE main screen, while navigating into a file \sphinxcode{\sphinxupquote{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.


\subsubsection{Managing files and buffers, basic editing}
\label{\detokenize{practical-tools/coqide:managing-files-and-buffers-basic-editing}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
Buffers may be edited as in any text editor, and classical basic
editing commands (Copy/Paste, …) are available in the \sphinxstyleemphasis{Edit} menu.
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.


\subsubsection{Interactive navigation into Coq scripts}
\label{\detokenize{practical-tools/coqide:interactive-navigation-into-coq-scripts}}
\sphinxAtStartPar
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).

\sphinxAtStartPar
In the figure {\hyperref[\detokenize{practical-tools/coqide:coqide-mainscreen}]{\sphinxcrossref{\DUrole{std,std-ref}{CoqIDE main screen}}}},
the running buffer is \sphinxcode{\sphinxupquote{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.

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{coqtop}}, you should never use
\sphinxcode{\sphinxupquote{Undo}} to go backward.

\sphinxAtStartPar
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\sphinxhyphen{}to\sphinxhyphen{}the\sphinxhyphen{}end
button depends on whether 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\sphinxhyphen{}handling applies when running several commands using
the "goto" button.

\sphinxAtStartPar
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).

\sphinxAtStartPar
There are other buttons on the 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.

\sphinxAtStartPar
The "gears" button submits proof terms to the Coq kernel for type checking.
When 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\sphinxhyphen{}checking of generated proof terms.
The presence of unchecked proof terms is indicated by \sphinxcode{\sphinxupquote{Qed}} statements that
have a subdued \sphinxstyleemphasis{being\sphinxhyphen{}processed} color (light blue by default), rather than the
processed color, though their preceding proofs have the processed color.

\sphinxAtStartPar
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.


\subsubsection{Commands and templates}
\label{\detokenize{practical-tools/coqide:commands-and-templates}}
\sphinxAtStartPar
The Templates menu allows using shortcuts to insert
commands. This is a nice way to proceed if you are not sure of the
syntax of the command you want.

\sphinxAtStartPar
Moreover, from this menu you can automatically insert templates of complex
commands like \sphinxcode{\sphinxupquote{Fixpoint}} that you can conveniently fill afterwards.


\subsubsection{Queries}
\label{\detokenize{practical-tools/coqide:queries}}
\noindent\sphinxincludegraphics{{coqide-queries}.png}

\sphinxAtStartPar
We call \sphinxstyleemphasis{query} any 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, 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.


\subsubsection{Compilation}
\label{\detokenize{practical-tools/coqide:compilation}}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Compile}} menu offers direct commands to:
\begin{itemize}
\item {} 
\sphinxAtStartPar
compile the current buffer

\item {} 
\sphinxAtStartPar
run a compilation using \sphinxcode{\sphinxupquote{make}}

\item {} 
\sphinxAtStartPar
go to the last compilation error

\item {} 
\sphinxAtStartPar
create a \sphinxcode{\sphinxupquote{Makefile}} using \sphinxcode{\sphinxupquote{coq\_makefile}}.

\end{itemize}


\subsubsection{Customizations}
\label{\detokenize{practical-tools/coqide:customizations}}
\sphinxAtStartPar
You may customize your environment using the menu Edit/Preferences. A new
window will be displayed, with several customization sections
presented as a notebook.

\sphinxAtStartPar
The first section is for selecting the text font used for scripts,
goal and message windows.

\sphinxAtStartPar
The second and third sections are for controlling colors and style of
the three main buffers. A predefined Coq highlighting style as well
as standard \DUrole{smallcaps}{GtkSourceView} styles are available. Other styles can be
added e.g. in \sphinxcode{\sphinxupquote{\$HOME/.local/share/gtksourceview\sphinxhyphen{}3.0/styles/}} (see
the general documentation about \DUrole{smallcaps}{GtkSourceView} for the various
possibilities). Note that the style of the rest of graphical part of
CoqIDE is not under the control of \DUrole{smallcaps}{GtkSourceView} but of GTK+ and
governed by files such as \sphinxcode{\sphinxupquote{settings.ini}} and \sphinxcode{\sphinxupquote{gtk.css}} in
\sphinxcode{\sphinxupquote{\$XDG\_CONFIG\_HOME/gtk\sphinxhyphen{}3.0}} or files in
\sphinxcode{\sphinxupquote{\$HOME/.themes/NameOfTheme/gtk\sphinxhyphen{}3.0}}, as well as the environment
variable \sphinxcode{\sphinxupquote{GTK\_THEME}} (search on internet for the various
possibilities).

\sphinxAtStartPar
The fourth section is for customizing the editor. It includes in
particular the ability to activate an Emacs mode named
micro\sphinxhyphen{}Proof\sphinxhyphen{}General (use the Help menu to know more about the
available bindings).

\sphinxAtStartPar
The next section is devoted to file management: you may configure
automatic saving of files, by periodically saving the contents into
files named \sphinxcode{\sphinxupquote{\#f\#}} for each opened file \sphinxcode{\sphinxupquote{f}}. You may also activate the
\sphinxstyleemphasis{revert} feature: in case a opened file is modified on the disk by a
third party, 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}}}}.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Externals}} section allows customizing the external commands for
compilation, printing, web browsing. In the browser command, you may
use \sphinxcode{\sphinxupquote{\%s}} to denote the URL to open, for example:
\sphinxcode{\sphinxupquote{firefox \sphinxhyphen{}remote "OpenURL(\%s)"}}.

\sphinxAtStartPar
Notice that these settings are saved in the file \sphinxcode{\sphinxupquote{coqiderc}} in the
\sphinxcode{\sphinxupquote{coq}} subdirectory of the user configuration directory which
is the value of \sphinxcode{\sphinxupquote{\$XDG\_CONFIG\_HOME}} if this environment variable is
set and which otherwise is \sphinxcode{\sphinxupquote{\$HOME/.config/}}.

\sphinxAtStartPar
A GTK+ accelerator keymap is saved under the name \sphinxcode{\sphinxupquote{coqide.keys}} in
the same \sphinxcode{\sphinxupquote{coq}} subdirectory of the user configuration directory. 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.


\subsubsection{Using Unicode symbols}
\label{\detokenize{practical-tools/coqide:using-unicode-symbols}}
\sphinxAtStartPar
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. Furthermore, CoqIDE conveniently provides a simple way to
input Unicode characters.


\paragraph{Displaying Unicode symbols}
\label{\detokenize{practical-tools/coqide:displaying-unicode-symbols}}
\sphinxAtStartPar
You just need to define suitable notations as described in the chapter
{\hyperref[\detokenize{user-extensions/syntax-extensions:syntax-extensions-and-notation-scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax extensions and notation scopes}}}}. For example, to use the
mathematical symbols ∀ and ∃, you may define:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{∀ x .. y , P}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{o}{..} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{y}\PYG{o}{,} \PYG{n}{P}\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}{:} \PYG{n}{type\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{∃ x .. y , P}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{exists} \PYG{n}{x}\PYG{o}{,} \PYG{o}{..} \PYG{o}{(}\PYG{k}{exists} \PYG{n}{y}\PYG{o}{,} \PYG{n}{P}\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}{:} \PYG{n}{type\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxAtStartPar
There exists a small set of such notations already defined, in the
file \sphinxcode{\sphinxupquote{utf8.v}} of Coq library, so you may enable them just by
\sphinxcode{\sphinxupquote{Require Import Unicode.Utf8}} inside CoqIDE, or equivalently,
by starting CoqIDE with \sphinxcode{\sphinxupquote{coqide \sphinxhyphen{}l utf8}}.

\sphinxAtStartPar
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
\sphinxcode{\sphinxupquote{GDK\_USE\_XFT}} to 1 or 0 respectively.


\paragraph{Bindings for input of Unicode symbols}
\label{\detokenize{practical-tools/coqide:bindings-for-input-of-unicode-symbols}}\label{\detokenize{practical-tools/coqide:coqide-unicode}}
\sphinxAtStartPar
CoqIDE supports a builtin mechanism to input non\sphinxhyphen{}ASCII symbols.
For example, to input \sphinxcode{\sphinxupquote{π}}, it suffices to type \sphinxcode{\sphinxupquote{\textbackslash{}pi}} then press the
combination of key \sphinxcode{\sphinxupquote{Shift+Space}} (default key binding). Often, it
suffices to type a prefix of the latex token, e.g. typing \sphinxcode{\sphinxupquote{\textbackslash{}p}}
then \sphinxcode{\sphinxupquote{Shift+Space}} suffices to insert a \sphinxcode{\sphinxupquote{π}}.

\sphinxAtStartPar
For several symbols, ASCII art is also recognized, e.g. \sphinxcode{\sphinxupquote{\textbackslash{}\sphinxhyphen{}>}} for a
right arrow, or \sphinxcode{\sphinxupquote{\textbackslash{}>=}} for a greater than or equal sign.

\sphinxAtStartPar
A larger number of latex tokens are supported by default. The full list
is available here:
\sphinxurl{https://github.com/coq/coq/blob/master/ide/coqide/default\_bindings\_src.ml}

\sphinxAtStartPar
Custom bindings may be added, as explained further on.

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
It remains possible to input non\sphinxhyphen{}ASCII symbols using system\sphinxhyphen{}wide
approaches independent of CoqIDE.
\end{sphinxadmonition}


\paragraph{Adding custom bindings}
\label{\detokenize{practical-tools/coqide:adding-custom-bindings}}
\sphinxAtStartPar
To extend the default set of bindings, create a file named \sphinxcode{\sphinxupquote{coqide.bindings}}
and place it in the same folder as \sphinxcode{\sphinxupquote{coqide.keys}}. This would be
the folder \sphinxcode{\sphinxupquote{\$XDG\_CONFIG\_HOME/coq}}, defaulting to \sphinxcode{\sphinxupquote{\textasciitilde{}/.config/coq}}
if \sphinxcode{\sphinxupquote{XDG\_CONFIG\_HOME}} is unset. The file \sphinxcode{\sphinxupquote{coqide.bindings}} should contain one
binding per line, in the form \sphinxcode{\sphinxupquote{\textbackslash{}key value}}, followed by an optional priority
integer. (The key and value should not contain any space character.)

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
Here is an example configuration file:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZbs{}par ||
\PYGZbs{}pi π 1
\PYGZbs{}le ≤ 1
\PYGZbs{}lambda λ 2
\PYGZbs{}lambdas λs
\end{sphinxVerbatim}
\end{sphinxadmonition}

\sphinxAtStartPar
Above, the priority number 1 on \sphinxcode{\sphinxupquote{\textbackslash{}pi}} indicates that the prefix \sphinxcode{\sphinxupquote{\textbackslash{}p}}
should resolve to \sphinxcode{\sphinxupquote{\textbackslash{}pi}}, and not to something else (e.g. \sphinxcode{\sphinxupquote{\textbackslash{}par}}).
Similarly, the above settings ensure than \sphinxcode{\sphinxupquote{\textbackslash{}l}} resolves to \sphinxcode{\sphinxupquote{\textbackslash{}le}},
and that \sphinxcode{\sphinxupquote{\textbackslash{}la}} resolves to \sphinxcode{\sphinxupquote{\textbackslash{}lambda}}.

\sphinxAtStartPar
It can be useful to work with per\sphinxhyphen{}project binding files. For this purpose
CoqIDE accepts a command line argument of the form
\sphinxcode{\sphinxupquote{\sphinxhyphen{}unicode\sphinxhyphen{}bindings file1,file2,...,fileN}}.
Each of the file tokens provided may consists of one of:
\begin{itemize}
\item {} 
\sphinxAtStartPar
a path to a custom bindings file,

\item {} 
\sphinxAtStartPar
the token \sphinxcode{\sphinxupquote{default}}, which resolves to the default bindings file,

\item {} 
\sphinxAtStartPar
the token \sphinxcode{\sphinxupquote{local}}, which resolves to the \sphinxcode{\sphinxupquote{coqide.bindings}} file
stored in the user configuration directory.

\end{itemize}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
If a filename other than the first one includes a "\textasciitilde{}" to refer
to the home directory, it won't be expanded properly. To work around that
issue, one should not use comas but instead repeat the flag, in the form:
\sphinxcode{\sphinxupquote{\sphinxhyphen{}unicode\sphinxhyphen{}bindings file1 .. \sphinxhyphen{}unicode\sphinxhyphen{}bindings fileN}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
If two bindings for a same token both have the same priority value
(or both have no priority value set), then the binding considered is
the one from the file that comes first on the command line.
\end{sphinxadmonition}


\paragraph{Character encoding for saved files}
\label{\detokenize{practical-tools/coqide:character-encoding-for-saved-files}}\label{\detokenize{practical-tools/coqide:character-encoding-saved-files}}
\sphinxAtStartPar
In the Files section of the preferences, the encoding option is
related to the way files are saved.

\sphinxAtStartPar
If you have no need to exchange files with non UTF\sphinxhyphen{}8 aware
applications, it is better to choose the UTF\sphinxhyphen{}8 encoding, since it
guarantees that your files will be read again without problems. (This
is because when CoqIDE reads a file, it tries to automatically detect
its character encoding.)

\sphinxAtStartPar
If you choose something else than UTF\sphinxhyphen{}8, then missing characters will
be written encoded by \sphinxcode{\sphinxupquote{x\{....\}}} or \sphinxcode{\sphinxupquote{x\{........\}}} where each dot is
an hexadecimal digit: the number between braces is the hexadecimal
Unicode index for the missing character.


\subsection{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
\sphinxAtStartPar
Enrico Tassi

\end{description}\end{quote}

\sphinxAtStartPar
This chapter explains how proofs can be asynchronously processed by
Coq. This feature improves the reactivity of the system when used in
interactive mode via CoqIDE. In addition, it allows 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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
This feature has some technical limitations that may make it
unsuitable for some use cases.

\sphinxAtStartPar
For example, in interactive mode, some errors coming from the kernel
of Coq are signaled late. The type of errors belonging to this
category are universe inconsistencies.

\sphinxAtStartPar
At the time of writing, only opaque proofs (ending with \sphinxcode{\sphinxupquote{Qed}} or
\sphinxcode{\sphinxupquote{Admitted}}) can be processed asynchronously.

\sphinxAtStartPar
Finally, asynchronous processing is disabled when running 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.


\subsubsection{Proof annotations}
\label{\detokenize{addendum/parallel-proof-processing:proof-annotations}}
\sphinxAtStartPar
To process a proof asynchronously 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/core/sections:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}).

\sphinxAtStartPar
When a section ends, 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{proofs/writing-proofs/proof-mode:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Entering and exiting proof mode}}}}) that
declares which section variables the theorem uses.

\sphinxAtStartPar
The presence of \sphinxcode{\sphinxupquote{Proof}} using is needed to process proofs asynchronously
in interactive mode.

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{.vo}} file, the list of section
variables used.


\paragraph{Automatic suggestion of proof annotations}
\label{\detokenize{addendum/parallel-proof-processing:automatic-suggestion-of-proof-annotations}}
\sphinxAtStartPar
The {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:flag.Suggest-Proof-Using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Suggest Proof Using}}}}} flag makes 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.


\subsubsection{Proof blocks and error resilience}
\label{\detokenize{addendum/parallel-proof-processing:proof-blocks-and-error-resilience}}
\sphinxAtStartPar
Coq 8.6 introduced a mechanism for error resilience: in interactive
mode Coq is able to completely check a document containing errors
instead of bailing out at the first failure.

\sphinxAtStartPar
Two kind of errors are supported: errors occurring in
commands and errors occurring in proofs.

\sphinxAtStartPar
To properly recover from a failing tactic, 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). Coq comes with four
kind of proof blocks, and an ML API to add new ones.
\begin{quote}\begin{description}
\item[{curly}] \leavevmode
\sphinxAtStartPar
blocks are delimited by \{ and \}, see Chapter {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof mode}}}}

\item[{par}] \leavevmode
\sphinxAtStartPar
blocks are atomic, i.e. just one tactic introduced by the \sphinxcode{\sphinxupquote{par:}}
goal selector

\item[{indent}] \leavevmode
\sphinxAtStartPar
blocks end with a tactic indented less than the previous one

\item[{bullet}] \leavevmode
\sphinxAtStartPar
blocks are delimited by two equal bullet signs at the same
indentation level

\end{description}\end{quote}


\paragraph{Caveats}
\label{\detokenize{addendum/parallel-proof-processing:caveats}}
\sphinxAtStartPar
When a command fails the subsequent error messages may be
bogus, i.e. caused by the first error. Error resilience for
commands can be switched off by passing \sphinxcode{\sphinxupquote{\sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}command\sphinxhyphen{}error\sphinxhyphen{}resilience off}}
to CoqIDE.

\sphinxAtStartPar
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 CoqIDE one of the following
options:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}tactic\sphinxhyphen{}error\sphinxhyphen{}resilience off}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}tactic\sphinxhyphen{}error\sphinxhyphen{}resilience all}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{\sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}tactic\sphinxhyphen{}error\sphinxhyphen{}resilience}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper-with-sub}{\DUrole{repeat}{blocktype}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}}}}}

\end{itemize}

\sphinxAtStartPar
Valid proof block types are: “curly”, “par”, “indent”, and “bullet”.


\subsubsection{Interactive mode}
\label{\detokenize{addendum/parallel-proof-processing:interactive-mode}}\label{\detokenize{addendum/parallel-proof-processing:id1}}
\sphinxAtStartPar
At the time of writing the only user interface supporting asynchronous
proof processing is CoqIDE.

\sphinxAtStartPar
When CoqIDE is started, two 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 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.

\sphinxAtStartPar
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{\sphinxhyphen{}async\sphinxhyphen{}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.


\paragraph{Caveats}
\label{\detokenize{addendum/parallel-proof-processing:id2}}
\sphinxAtStartPar
The number of worker processes can be increased by passing CoqIDE
the \sphinxcode{\sphinxupquote{\sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}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.

\sphinxAtStartPar
To disable this feature, one can pass the \sphinxcode{\sphinxupquote{\sphinxhyphen{}async\sphinxhyphen{}proofs off}} flag to
CoqIDE. Conversely, on Windows, where the feature is disabled by
default, pass the \sphinxcode{\sphinxupquote{\sphinxhyphen{}async\sphinxhyphen{}proofs on}} flag to enable it.

\sphinxAtStartPar
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{\sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}delegation\sphinxhyphen{}threshold}}. Default is 0.03 seconds.


\subsubsection{Batch mode}
\label{\detokenize{addendum/parallel-proof-processing:batch-mode}}\begin{quote}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\sphinxhyphen{}vio}} flag is subsumed, for most practical usage, by the
the more recent \sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} flag. See {\hyperref[\detokenize{practical-tools/coq-commands:compiled-interfaces}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled interfaces (produced using \sphinxhyphen{}vos)}}}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
When working with \sphinxcode{\sphinxupquote{.vio}} files, do not use the \sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} option at
the same time, otherwise stale files might get loaded when executing
a \sphinxcode{\sphinxupquote{Require}}. Indeed, the loading of a nonempty \sphinxcode{\sphinxupquote{.vos}} file is
assigned higher priority than the loading of a \sphinxcode{\sphinxupquote{.vio}} file.
\end{sphinxadmonition}
\end{quote}

\sphinxAtStartPar
When Coq is used as a batch compiler by running \sphinxcode{\sphinxupquote{coqc}}, it produces
a \sphinxcode{\sphinxupquote{.vo}} file for each \sphinxcode{\sphinxupquote{.v}} file. A \sphinxcode{\sphinxupquote{.vo}} file contains, among other
things, theorem statements and proofs. Hence to produce a .vo Coq
need to process all the proofs of the \sphinxcode{\sphinxupquote{.v}} file.

\sphinxAtStartPar
The asynchronous processing of proofs can decouple the generation of a
compiled file (like the \sphinxcode{\sphinxupquote{.vo}} one) that can be loaded by \sphinxcode{\sphinxupquote{Require}} from the
generation and checking of the proof objects. The \sphinxcode{\sphinxupquote{\sphinxhyphen{}vio}} flag can be
passed to \sphinxcode{\sphinxupquote{coqc}} to produce, quickly, \sphinxcode{\sphinxupquote{.vio}} files.
Alternatively, when using a Makefile produced by \sphinxcode{\sphinxupquote{coq\_makefile}},
the \sphinxcode{\sphinxupquote{vio}} target can be used to compile all files using the \sphinxcode{\sphinxupquote{\sphinxhyphen{}vio}} flag.

\sphinxAtStartPar
A \sphinxcode{\sphinxupquote{.vio}} file can be loaded using \sphinxcode{\sphinxupquote{Require}} exactly as a \sphinxcode{\sphinxupquote{.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 \sphinxcode{\sphinxupquote{.vio}} file does not contain proof
objects, but proof tasks, i.e. what a worker process can transform
into a proof object.

\sphinxAtStartPar
Compiling a set of files with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}vio}} flag allows one to work,
interactively, on any file without waiting for all the proofs to be
checked.

\sphinxAtStartPar
When working interactively, one can fully check all the \sphinxcode{\sphinxupquote{.v}} files by
running \sphinxcode{\sphinxupquote{coqc}} as usual.

\sphinxAtStartPar
Alternatively one can turn each \sphinxcode{\sphinxupquote{.vio}} into the corresponding \sphinxcode{\sphinxupquote{.vo}}. All
.vio files can be processed in parallel, hence this alternative might
be faster. The command \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}schedule\sphinxhyphen{}vio2vo 2 a b c}} can be used to
obtain a good scheduling for two workers to produce \sphinxcode{\sphinxupquote{a.vo}}, \sphinxcode{\sphinxupquote{b.vo}}, and
\sphinxcode{\sphinxupquote{c.vo}}. When using a Makefile produced by \sphinxcode{\sphinxupquote{coq\_makefile}}, the \sphinxcode{\sphinxupquote{vio2vo}} target
can be used for that purpose. Variable \sphinxcode{\sphinxupquote{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 \sphinxcode{\sphinxupquote{.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 \sphinxcode{\sphinxupquote{.vo}} files are (recursively) loaded with \sphinxcode{\sphinxupquote{Require}}.

\sphinxAtStartPar
There is an extra, possibly even faster, alternative: just check the
proof tasks stored in \sphinxcode{\sphinxupquote{.vio}} files without producing the \sphinxcode{\sphinxupquote{.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{coqc \sphinxhyphen{}schedule\sphinxhyphen{}vio\sphinxhyphen{}checking 6 a b c}} command can be used to obtain a
good scheduling for 6 workers to check all the proof tasks of \sphinxcode{\sphinxupquote{a.vio}},
\sphinxcode{\sphinxupquote{b.vio}}, and \sphinxcode{\sphinxupquote{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 \sphinxcode{\sphinxupquote{.vio}} files. Variable \sphinxcode{\sphinxupquote{J}}
should be set to the number of workers, e.g. \sphinxcode{\sphinxupquote{make checkproofs J=6}}. As
when converting \sphinxcode{\sphinxupquote{.vio}} files to \sphinxcode{\sphinxupquote{.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 \sphinxcode{\sphinxupquote{Type}} hierarchy.


\subsubsection{Limiting the number of parallel workers}
\label{\detokenize{addendum/parallel-proof-processing:limiting-the-number-of-parallel-workers}}
\sphinxAtStartPar
Many Coq processes may run on the same computer, and each of them may
start many additional worker processes. The \sphinxcode{\sphinxupquote{coqworkmgr}} utility lets
one limit the number of workers, globally.

\sphinxAtStartPar
The utility accepts the \sphinxcode{\sphinxupquote{\sphinxhyphen{}j}} argument to specify the maximum number of
workers (defaults to 2). \sphinxcode{\sphinxupquote{coqworkmgr}} automatically starts in the
background and prints an environment variable assignment
like \sphinxcode{\sphinxupquote{COQWORKMGR\_SOCK=localhost:45634}}. The user must set this variable
in all the shells from which Coq processes will be started. If one
uses just one terminal running the bash shell, then
\sphinxcode{\sphinxupquote{export ‘coqworkmgr \sphinxhyphen{}j 4‘}} will do the job.

\sphinxAtStartPar
After that, all Coq processes, e.g. \sphinxcode{\sphinxupquote{coqide}} and \sphinxcode{\sphinxupquote{coqc}}, will respect the
limit, globally.


\chapter{Appendix}
\label{\detokenize{index:appendix}}

\section{History and recent changes}
\label{\detokenize{appendix/history-and-changes/index:history-and-recent-changes}}\label{\detokenize{appendix/history-and-changes/index:history-and-changes}}\label{\detokenize{appendix/history-and-changes/index::doc}}
\sphinxAtStartPar
This chapter is divided in two parts.  The first one is about the
{\hyperref[\detokenize{history:history}]{\sphinxcrossref{\DUrole{std,std-ref}{early history of Coq}}}} and is presented in
chronological order.  The second one provides {\hyperref[\detokenize{changes:changes}]{\sphinxcrossref{\DUrole{std,std-ref}{release notes
about recent versions of Coq}}}} and is presented in reverse
chronological order.  When updating your copy of Coq to a new version
(especially a new major version), it is strongly recommended that you
read the corresponding release notes.  They may contain advice that
will help you understand the differences with the previous version and
upgrade your projects.


\subsection{Early history of Coq}
\label{\detokenize{history:early-history-of-coq}}\label{\detokenize{history:history}}\label{\detokenize{history::doc}}

\subsubsection{Historical roots}
\label{\detokenize{history:historical-roots}}
\sphinxAtStartPar
Coq is a proof assistant for higher\sphinxhyphen{}order logic, allowing the
development of computer programs consistent with their formal
specification. It is the result of about ten years %
\begin{footnote}[65]\sphinxAtStartFootnote
At the time of writing, i.e. 1995.
%
\end{footnote} 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.

\sphinxAtStartPar
The logical language used by 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
λ\sphinxhyphen{}calculus occurred with Church’s \sphinxstyleemphasis{Simple Theory of
Types}. The λ\sphinxhyphen{}calculus notation, originally used for
expressing functionality, could also be used as an encoding of natural
deduction proofs. This Curry\sphinxhyphen{}Howard isomorphism was used by N. de Bruijn
in the \sphinxstyleemphasis{Automath} project, the first full\sphinxhyphen{}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\sphinxhyphen{}Howard isomorphism, notable achievements in proof
theory saw the emergence of two type\sphinxhyphen{}theoretic frameworks; the first
one, Martin\sphinxhyphen{}Löf’s \sphinxstyleemphasis{Intuitionistic Theory of Types}, attempts a new
foundation of mathematics on constructive principles. The second one,
Girard’s polymorphic λ\sphinxhyphen{}calculus \(F_\omega\), is a
very strong functional system in which we may represent higher\sphinxhyphen{}order
logic proof structures. Combining both systems in a higher\sphinxhyphen{}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\sphinxhyphen{}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.

\sphinxAtStartPar
Automated theorem\sphinxhyphen{}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\sphinxhyphen{}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\sphinxhyphen{}aided proof\sphinxhyphen{}checking. The most notable
proof\sphinxhyphen{}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\sphinxhyphen{}prover, an automation of primitive recursion over
inductive data types. While the Boyer\sphinxhyphen{}Moore theorem\sphinxhyphen{}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\sphinxhyphen{}level
functional meta\sphinxhyphen{}language, ML.

\sphinxAtStartPar
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\sphinxhyphen{}order logic. Development of a systematic \sphinxstyleemphasis{programming logic},
based on extensions of Martin\sphinxhyphen{}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\sphinxhyphen{}time systems taking
advantage of special hardware, debuggers, and the like. We hope that Coq
can be of use to researchers interested in experimenting with this new
methodology.


\subsubsection{Versions 1 to 5}
\label{\detokenize{history:versions-1-to-5}}
\begin{sphinxadmonition}{note}{Note:}
\sphinxAtStartPar
This summary was written in 1995 together with the previous
section and formed the initial version of the Credits chapter.

\sphinxAtStartPar
A more comprehensive description of these early versions is available
in the following subsections, which come from a document written in
September 2015 by Gérard Huet, Thierry Coquand and Christine Paulin.
\end{sphinxadmonition}

\sphinxAtStartPar
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\sphinxhyphen{}checker for CoC seen as a typed
λ\sphinxhyphen{}calculus, called the \sphinxstyleemphasis{Constructive Engine}. This engine
was operated through a high\sphinxhyphen{}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
λ\sphinxhyphen{}terms. A section mechanism, designed and implemented by
G. Dowek, allowed hierarchical developments of mathematical theories.
This high\sphinxhyphen{}level language was called the \sphinxstyleemphasis{Mathematical Vernacular}.
Furthermore, an interactive \sphinxstyleemphasis{Theorem Prover} permitted the incremental
construction of proof trees in a top\sphinxhyphen{}down manner, subgoaling recursively
and backtracking from dead\sphinxhyphen{}ends. 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\sphinxhyphen{}interface, relying
on a CAML\sphinxhyphen{}X interface by D. de Rauglaudre, was designed and implemented
by A. Felty. It allowed operation of the theorem\sphinxhyphen{}prover through the
manipulation of windows, menus, mouse\sphinxhyphen{}sensitive buttons, and other
widgets. This system (Version 5.6) was released in 1991.

\sphinxAtStartPar
Coq was ported to the new implementation Caml\sphinxhyphen{}light of X. Leroy and D.
Doligez by D. de Rauglaudre (Version 5.7) in 1992. A new version of 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\sphinxhyphen{}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\sphinxhyphen{}Sophia\sphinxhyphen{}Antipolis.

\sphinxAtStartPar
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 Coq (V5.9).

\sphinxAtStartPar
The version V5.10 of 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\sphinxhyphen{}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 {} 
\sphinxAtStartPar
User\sphinxhyphen{}programmable tactics are allowed

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

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

\item {} 
\sphinxAtStartPar
Syntactic definitions allow convenient abbreviations

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

\end{itemize}

\sphinxAtStartPar
In the Fall of 1994, C. Paulin\sphinxhyphen{}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\sphinxhyphen{}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}


\paragraph{Version 1}
\label{\detokenize{history:version-1}}
\sphinxAtStartPar
This software is a prototype type checker for a higher\sphinxhyphen{}order logical
formalism known as the Theory of Constructions, presented in his PhD
thesis by Thierry Coquand, with influences from Girard's system F and
de Bruijn's Automath.  The metamathematical analysis of the system is
the PhD work of Thierry Coquand. The software is mostly the work of
Gérard Huet.  Most of the mathematical examples verified with the
software are due to Thierry Coquand.

\sphinxAtStartPar
The programming language of the CONSTR software (as it was called at
the time) was a version of ML adapted from the Edinburgh LCF system
and running on a LISP backend. The main improvements from the original
LCF ML were that ML was compiled rather than interpreted (Gérard Huet
building on the original translator by Lockwood Morris), and that it
was enriched by recursively defined types (work of Guy
Cousineau). This ancestor of CAML was used and improved by Larry
Paulson for his implementation of Cambridge LCF.

\sphinxAtStartPar
Software developments of this prototype occurred from late 1983 to
early 1985.

\sphinxAtStartPar
Version 1.10 was frozen on December 22nd 1984. It is the version used
for the examples in Thierry Coquand's thesis, defended on January 31st
1985. There was a unique binding operator, used both for universal
quantification (dependent product) at the level of types and
functional abstraction (λ) at the level of terms/proofs, in the manner
of Automath. Substitution (λ\sphinxhyphen{}reduction) was implemented using de
Bruijn's indexes.

\sphinxAtStartPar
Version 1.11 was frozen on February 19th, 1985. It is the version used
for the examples in the paper: T. Coquand, G. Huet. \sphinxstyleemphasis{Constructions: A
Higher Order Proof System for Mechanizing Mathematics} {[}\hyperlink{cite.zebibliography:id6}{CH85}{]}.

\sphinxAtStartPar
Christine Paulin joined the team at this point, for her DEA research
internship.  In her DEA memoir (August 1985) she presents developments
for the \sphinxstyleemphasis{lambo} function – \(\text{lambo}(f)(n)\) computes the minimal
\(m\) such that \(f(m)\) is greater than \(n\), for \(f\)
an increasing integer function, a challenge for constructive mathematics.
She also encoded the majority voting algorithm of Boyer and Moore.


\paragraph{Version 2}
\label{\detokenize{history:version-2}}
\sphinxAtStartPar
The formal system, now renamed as the \sphinxstyleemphasis{Calculus of Constructions}, was
presented with a proof of consistency and comparisons with proof
systems of Per Martin Löf, Girard, and the Automath family of N. de
Bruijn, in the paper: T. Coquand and G. Huet. \sphinxstyleemphasis{The Calculus of
Constructions} {[}\hyperlink{cite.zebibliography:id7}{CH86b}{]}.

\sphinxAtStartPar
An abstraction of the software design, in the form of an abstract
machine for proof checking, and a fuller sequence of mathematical
developments was presented in: T. Coquand, G. Huet. \sphinxstyleemphasis{Concepts
Mathématiques et Informatiques Formalisés dans le Calcul des
Constructions} {[}\hyperlink{cite.zebibliography:id8}{CH86a}{]}.

\sphinxAtStartPar
Version 2.8 was frozen on December 16th, 1985, and served for
developing the examples in the above papers.

\sphinxAtStartPar
This calculus was then enriched in version 2.9 with a cumulative
hierarchy of universes. Universe levels were initially explicit
natural numbers.  Another improvement was the possibility of automatic
synthesis of implicit type arguments, relieving the user of tedious
redundant declarations.

\sphinxAtStartPar
Christine Paulin wrote an article \sphinxstyleemphasis{Algorithm development in the
Calculus of Constructions} {[}\hyperlink{cite.zebibliography:id40}{Moh86}{]}. Besides \sphinxstyleemphasis{lambo} and \sphinxstyleemphasis{majority},
she presents \sphinxstyleemphasis{quicksort} and a text formatting algorithm.

\sphinxAtStartPar
Version 2.13 of the Calculus of Constructions with universes was
frozen on June 25th, 1986.

\sphinxAtStartPar
A synthetic presentation of type theory along constructive lines with
ML algorithms was given by Gérard Huet in his May 1986 CMU course
notes \sphinxstyleemphasis{Formal Structures for Computation and Deduction}. Its chapter
\sphinxstyleemphasis{Induction and Recursion in the Theory of Constructions} was presented
as an invited paper at the Joint Conference on Theory and Practice of
Software Development TAPSOFT’87 at Pise in March 1987, and published
as \sphinxstyleemphasis{Induction Principles Formalized in the Calculus of
Constructions} {[}\hyperlink{cite.zebibliography:id28}{Hue88}{]}.


\paragraph{Version 3}
\label{\detokenize{history:version-3}}
\sphinxAtStartPar
This version saw the beginning of proof automation, with a search
algorithm inspired from PROLOG and the applicative logic programming
programs of the course notes \sphinxstyleemphasis{Formal structures for computation and
deduction}.  The search algorithm was implemented in ML by Thierry
Coquand.  The proof system could thus be used in two modes: proof
verification and proof synthesis, with tactics such as \sphinxcode{\sphinxupquote{AUTO}}.

\sphinxAtStartPar
The implementation language was now called CAML, for Categorical
Abstract Machine Language. It used as backend the LLM3 virtual machine
of Le Lisp by Jérôme Chailloux. The main developers of CAML were
Michel Mauny, Ascander Suarez and Pierre Weis.

\sphinxAtStartPar
V3.1 was started in the summer of 1986, V3.2 was frozen at the end of
November 1986. V3.4 was developed in the first half of 1987.

\sphinxAtStartPar
Thierry Coquand held a post\sphinxhyphen{}doctoral position in Cambridge University
in 1986\sphinxhyphen{}87, where he developed a variant implementation in SML, with
which he wrote some developments on fixpoints in Scott's domains.


\paragraph{Version 4}
\label{\detokenize{history:version-4}}
\sphinxAtStartPar
This version saw the beginning of program extraction from proofs, with
two varieties of the type \sphinxcode{\sphinxupquote{Prop}} of propositions, indicating
constructive intent.  The proof extraction algorithms were implemented
by Christine Paulin\sphinxhyphen{}Mohring.

\sphinxAtStartPar
V4.1 was frozen on July 24th, 1987. It had a first identified library
of mathematical developments (directory \sphinxcode{\sphinxupquote{exemples}}), with libraries
\sphinxcode{\sphinxupquote{Logic}} (containing impredicative encodings of intuitionistic logic and
algebraic primitives for booleans, natural numbers and list), \sphinxcode{\sphinxupquote{Peano}}
developing second\sphinxhyphen{}order Peano arithmetic, \sphinxcode{\sphinxupquote{Arith}} defining addition,
multiplication, euclidean division and factorial. Typical developments
were the Knaster\sphinxhyphen{}Tarski theorem and Newman's lemma from rewriting
theory.

\sphinxAtStartPar
V4.2 was a joint development of a team consisting of Thierry Coquand,
Gérard Huet and Christine Paulin\sphinxhyphen{}Mohring. A file V4.2.log records the
log of changes.  It was frozen on September 1987 as the last version
implemented in CAML 2.3, and V4.3 followed on CAML 2.5, a more stable
development system.

\sphinxAtStartPar
V4.3 saw the first top\sphinxhyphen{}level of the system. Instead of evaluating
explicit quotations, the user could develop his mathematics in a
high\sphinxhyphen{}level language called the mathematical vernacular (following
Automath terminology).  The user could develop files in the vernacular
notation (with \sphinxcode{\sphinxupquote{.v}} extension) which were now separate from the \sphinxcode{\sphinxupquote{ml}}
sources of the implementation.  Gilles Dowek joined the team to
develop the vernacular language as his DEA internship research.

\sphinxAtStartPar
A notion of sticky constant was introduced, in order to keep names of
lemmas when local hypotheses of proofs were discharged. This gave a
notion of global mathematical environment with local sections.

\sphinxAtStartPar
Another significant practical change was that the system, originally
developed on the VAX central computer of our lab, was transferred on
SUN personal workstations, allowing a level of distributed
development.  The extraction algorithm was modified, with three
annotations \sphinxcode{\sphinxupquote{Pos}}, \sphinxcode{\sphinxupquote{Null}} and \sphinxcode{\sphinxupquote{Typ}} decorating the sorts \sphinxcode{\sphinxupquote{Prop}}
and \sphinxcode{\sphinxupquote{Type}}.

\sphinxAtStartPar
Version 4.3 was frozen at the end of November 1987, and was
distributed to an early community of users (among those were Hugo
Herbelin and Loic Colson).

\sphinxAtStartPar
V4.4 saw the first version of (encoded) inductive types.  Now natural
numbers could be defined as:

\begin{sphinxVerbatim}[commandchars=\\\{\}]
[source, coq]
Inductive NAT : Prop = O : NAT | Succ : NAT\PYGZhy{}\PYGZgt{}NAT.
\end{sphinxVerbatim}

\sphinxAtStartPar
These inductive types were encoded impredicatively in the calculus,
using a subsystem \sphinxstyleemphasis{rec} due to Christine Paulin.  V4.4 was frozen on
March 6th 1988.

\sphinxAtStartPar
Version 4.5 was the first one to support inductive types and program
extraction.  Its banner was \sphinxstyleemphasis{Calcul des Constructions avec
Réalisations et Synthèse}.  The vernacular language was enriched to
accommodate extraction commands.

\sphinxAtStartPar
The verification engine design was presented as: G. Huet. \sphinxstyleemphasis{The
Constructive Engine}. Version 4.5. Invited Conference, 2nd European
Symposium on Programming, Nancy, March 88.  The final paper,
describing the V4.9 implementation, appeared in: A perspective in
Theoretical Computer Science, Commemorative Volume in memory of Gift
Siromoney, Ed. R. Narasimhan, World Scientific Publishing, 1989.

\sphinxAtStartPar
Version 4.5 was demonstrated in June 1988 at the YoP Institute on
Logical Foundations of Functional Programming organized by Gérard Huet
at Austin, Texas.

\sphinxAtStartPar
Version 4.6 was started during the summer of 1988. Its main
improvement was the complete rehaul of the proof synthesis engine by
Thierry Coquand, with a tree structure of goals.

\sphinxAtStartPar
Its source code was communicated to Randy Pollack on September 2nd
1988.  It evolved progressively into LEGO, proof system for Luo's
formalism of Extended Calculus of Constructions.

\sphinxAtStartPar
The discharge tactic was modified by Gérard Huet to allow for
inter\sphinxhyphen{}dependencies in discharged lemmas. Christine Paulin improved the
inductive definition scheme in order to accommodate predicates of any
arity.

\sphinxAtStartPar
Version 4.7 was started on September 6th, 1988.

\sphinxAtStartPar
This version starts exploiting the CAML notion of module in order to
improve the modularity of the implementation. Now the term verifier is
identified as a proper module Machine, which the structure of its
internal data structures being hidden and thus accessible only through
the legitimate operations.  This machine (the constructive engine) was
the trusted core of the implementation. The proof synthesis mechanism
was a separate proof term generator. Once a complete proof term was
synthesized with the help of tactics, it was entirely re\sphinxhyphen{}checked by
the engine. Thus there was no need to certify the tactics, and the
system took advantage of this fact by having tactics ignore the
universe levels, universe consistency check being relegated to the
final type checking pass. This induced a certain puzzlement in early
users who saw, after a successful proof search, their \sphinxcode{\sphinxupquote{QED}} followed
by silence, followed by a failure message due to a universe
inconsistency…

\sphinxAtStartPar
The set of examples comprise set theory experiments by Hugo Herbelin,
and notably the Schroeder\sphinxhyphen{}Bernstein theorem.

\sphinxAtStartPar
Version 4.8, started on October 8th, 1988, saw a major
re\sphinxhyphen{}implementation of the abstract syntax type \sphinxcode{\sphinxupquote{constr}}, separating
variables of the formalism and metavariables denoting incomplete terms
managed by the search mechanism.  A notion of level (with three values
\sphinxcode{\sphinxupquote{TYPE}}, \sphinxcode{\sphinxupquote{OBJECT}} and \sphinxcode{\sphinxupquote{PROOF}}) is made explicit and a type judgement
clarifies the constructions, whose implementation is now fully
explicit. Structural equality is speeded up by using pointer equality,
yielding spectacular improvements. Thierry Coquand adapts the proof
synthesis to the new representation, and simplifies pattern matching
to first\sphinxhyphen{}order predicate calculus matching, with important performance
gain.

\sphinxAtStartPar
A new representation of the universe hierarchy is then defined by
Gérard Huet.  Universe levels are now implemented implicitly, through
a hidden graph of abstract levels constrained with an order relation.
Checking acyclicity of the graph insures well\sphinxhyphen{}foundedness of the
ordering, and thus consistency. This was documented in a memo \sphinxstyleemphasis{Adding
Type:Type to the Calculus of Constructions} which was never published.

\sphinxAtStartPar
The development version is released as a stable 4.8 at the end of
1988.

\sphinxAtStartPar
Version 4.9 is released on March 1st 1989, with the new "elastic"
universe hierarchy.

\sphinxAtStartPar
The spring of 1989 saw the first attempt at documenting the system
usage, with a number of papers describing the formalism:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstyleemphasis{Metamathematical Investigations of a Calculus of Constructions}, by
Thierry Coquand {[}\hyperlink{cite.zebibliography:id9}{Coq89}{]},

\item {} 
\sphinxAtStartPar
\sphinxstyleemphasis{Inductive definitions in the Calculus of Constructions}, by
Christine Paulin\sphinxhyphen{}Mohrin,

\item {} 
\sphinxAtStartPar
\sphinxstyleemphasis{Extracting Fω's programs from proofs in the Calculus of
Constructions}, by Christine Paulin\sphinxhyphen{}Mohring* {[}\hyperlink{cite.zebibliography:id41}{PM89}{]},

\item {} 
\sphinxAtStartPar
\sphinxstyleemphasis{The Constructive Engine}, by Gérard Huet {[}\hyperlink{cite.zebibliography:id29}{Hue89}{]},

\end{itemize}

\sphinxAtStartPar
as well as a number of user guides:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstyleemphasis{A short user's guide for the Constructions}, Version 4.10, by Gérard Huet

\item {} 
\sphinxAtStartPar
\sphinxstyleemphasis{A Vernacular Syllabus}, by Gilles Dowek.

\item {} 
\sphinxAtStartPar
\sphinxstyleemphasis{The Tactics Theorem Prover, User's guide}, Version 4.10, by Thierry
Coquand.

\end{itemize}

\sphinxAtStartPar
Stable V4.10, released on May 1st, 1989, was then a mature system,
distributed with CAML V2.6.

\sphinxAtStartPar
In the mean time, Thierry Coquand and Christine Paulin\sphinxhyphen{}Mohring had
been investigating how to add native inductive types to the Calculus
of Constructions, in the manner of Per Martin\sphinxhyphen{}Löf's Intuitionistic
Type Theory. The impredicative encoding had already been presented in:
F. Pfenning and C. Paulin\sphinxhyphen{}Mohring. \sphinxstyleemphasis{Inductively defined types in the
Calculus of Constructions} {[}\hyperlink{cite.zebibliography:id43}{PPM89}{]}. An extension of the calculus
with primitive inductive types appeared in: T. Coquand and
C. Paulin\sphinxhyphen{}Mohring. \sphinxstyleemphasis{Inductively defined types} {[}\hyperlink{cite.zebibliography:id14}{CP90}{]}.

\sphinxAtStartPar
This led to the Calculus of Inductive Constructions, logical formalism
implemented in Versions 5 upward of the system, and documented in:
C. Paulin\sphinxhyphen{}Mohring. \sphinxstyleemphasis{Inductive Definitions in the System Coq \sphinxhyphen{} Rules
and Properties} {[}\hyperlink{cite.zebibliography:id42}{PM93b}{]}.

\sphinxAtStartPar
The last version of CONSTR is Version 4.11, which was last distributed
in the spring of 1990. It was demonstrated at the first workshop of
the European Basic Research Action Logical Frameworks In Sophia
Antipolis in May 1990.


\paragraph{Version 5}
\label{\detokenize{history:version-5}}
\sphinxAtStartPar
At the end of 1989, Version 5.1 was started, and renamed as the system
Coq for the Calculus of Inductive Constructions. It was then ported to
the new stand\sphinxhyphen{}alone implementation of ML called Caml\sphinxhyphen{}light.

\sphinxAtStartPar
In 1990 many changes occurred. Thierry Coquand left for Chalmers
University in Göteborg. Christine Paulin\sphinxhyphen{}Mohring took a CNRS
researcher position at the LIP laboratory of École Normale Supérieure
de Lyon. Project Formel was terminated, and gave rise to two teams:
Cristal at INRIA\sphinxhyphen{}Roquencourt, that continued developments in
functional programming with Caml\sphinxhyphen{}light then OCaml, and Coq, continuing
the type theory research, with a joint team headed by Gérard Huet at
INRIA\sphinxhyphen{}Rocquencourt and Christine Paulin\sphinxhyphen{}Mohring at the LIP laboratory
of CNRS\sphinxhyphen{}ENS Lyon.

\sphinxAtStartPar
Chetan Murthy joined the team in 1991 and became the main software
architect of Version 5. He completely rehauled the implementation for
efficiency.  Versions 5.6 and 5.8 were major distributed versions,
with complete documentation and a library of users' developments. The
use of the RCS revision control system, and systematic ChangeLog
files, allow a more precise tracking of the software developments.

\begin{DUlineblock}{0em}
\item[] September 2015 +
\item[] Thierry Coquand, Gérard Huet and Christine Paulin\sphinxhyphen{}Mohring.
\item[] 
\end{DUlineblock}


\subsubsection{Versions 6}
\label{\detokenize{history:versions-6}}

\paragraph{Version 6.1}
\label{\detokenize{history:version-6-1}}
\sphinxAtStartPar
The present version 6.1 of 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.

\sphinxAtStartPar
The new version provides powerful tools for easier developments.

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

\sphinxAtStartPar
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.

\sphinxAtStartPar
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\sphinxhyphen{}free Presburger Arithmetic. Both functionalities have been
integrated to the Coq system by Hugo Herbelin.

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

\sphinxAtStartPar
Finally the organisation of the Coq distribution has been supervised by
Jean\sphinxhyphen{}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}


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

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

\sphinxAtStartPar
Bruno Barras wrote new, more efficient reduction functions.

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

\sphinxAtStartPar
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\sphinxhyphen{}Christophe Filliâtre introduced a tactic for refining a goal, using
a proof term with holes as a proof scheme.

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

\sphinxAtStartPar
Henri Laulhère produced the Coq distribution for the Windows
environment.

\sphinxAtStartPar
Finally, Hugo Herbelin was the main coordinator of the Coq documentation
with principal contributions by Bruno Barras, David Delahaye,
Jean\sphinxhyphen{}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}


\paragraph{Version 6.3}
\label{\detokenize{history:version-6-3}}
\sphinxAtStartPar
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.

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

\sphinxAtStartPar
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}}.

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

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

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

\sphinxAtStartPar
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.

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

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


\subsubsection{Versions 7}
\label{\detokenize{history:versions-7}}

\paragraph{Summary of changes}
\label{\detokenize{history:summary-of-changes}}
\sphinxAtStartPar
The version V7 is a new implementation started in September 1999 by
Jean\sphinxhyphen{}Christophe Filliâtre. This is a major revision with respect to the
internal architecture of the system. The 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.

\sphinxAtStartPar
Jean\sphinxhyphen{}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\sphinxhyphen{}structures in order to get more sharing, to prepare the addition of
modules and also to get closer to a certified kernel.

\sphinxAtStartPar
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 Coq internal structures and the
optimisation of the system. He added basic tactics for forward reasoning
and coercions in patterns.

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

\sphinxAtStartPar
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.

\sphinxAtStartPar
Jean\sphinxhyphen{}Christophe Filliâtre and Pierre Letouzey redesigned a new
extraction procedure from Coq terms to Caml or Haskell programs. This
new extraction procedure, unlike the one implemented in previous version
of 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\sphinxhyphen{}Christophe Filliâtre wrote \sphinxcode{\sphinxupquote{coqdoc}}, a documentation
tool for Coq libraries usable from version 7.2.

\sphinxAtStartPar
Bruno Barras improved the efficiency of the reduction algorithm and the
confidence level in the correctness of Coq critical type checking
algorithm.

\sphinxAtStartPar
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/}).

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

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

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

\sphinxAtStartPar
Pierre Crégut developed a new, reflection\sphinxhyphen{}based version of the Omega
decision procedure.

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

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

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

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

\sphinxAtStartPar
The development was coordinated by C. Paulin.

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

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

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


\paragraph{Details of changes in 7.0 and 7.1}
\label{\detokenize{history:details-of-changes-in-7-0-and-7-1}}
\sphinxAtStartPar
Notes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
items followed by (**) are important sources of incompatibilities

\item {} 
\sphinxAtStartPar
items followed by (*) may exceptionally be sources of incompatibilities

\item {} 
\sphinxAtStartPar
items followed by (+) have been introduced in version 7.0

\end{itemize}


\subparagraph{Main novelties}
\label{\detokenize{history:main-novelties}}
\sphinxAtStartPar
References are to Coq 7.1 reference manual
\begin{itemize}
\item {} 
\sphinxAtStartPar
New primitive let\sphinxhyphen{}in construct (see sections 1.2.8 and )

\item {} 
\sphinxAtStartPar
Long names (see sections 2.6 and 2.7)

\item {} 
\sphinxAtStartPar
New high\sphinxhyphen{}level tactic language (see chapter 10)

\item {} 
\sphinxAtStartPar
Improved search facilities (see section 5.2)

\item {} 
\sphinxAtStartPar
New extraction algorithm managing the Type level (see chapter 17)

\item {} 
\sphinxAtStartPar
New rewriting tactic for arbitrary equalities (see chapter 19)

\item {} 
\sphinxAtStartPar
New tactic Field to decide equalities on commutative fields (see 7.11)

\item {} 
\sphinxAtStartPar
New tactic Fourier to solve linear inequalities on reals numbers (see 7.11)

\item {} 
\sphinxAtStartPar
New tactics for induction/case analysis in "natural" style (see 7.7)

\item {} 
\sphinxAtStartPar
Deep restructuration of the code (safer, simpler and more efficient)

\item {} 
\sphinxAtStartPar
Export of theories to XML for publishing and rendering purposes
(see \sphinxurl{http://www.cs.unibo.it/helm})

\end{itemize}


\subparagraph{Details of changes}
\label{\detokenize{history:details-of-changes}}

\subparagraph{Language: new "let\sphinxhyphen{}in" construction}
\label{\detokenize{history:language-new-let-in-construction}}\begin{itemize}
\item {} 
\sphinxAtStartPar
New construction for local definitions (let\sphinxhyphen{}in) with syntax {[}x:=u{]}t (*)(+)

\item {} 
\sphinxAtStartPar
Local definitions allowed in Record (a.k.a. record à la Randy Pollack)

\end{itemize}


\subparagraph{Language: long names}
\label{\detokenize{history:language-long-names}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Each construction has a unique absolute names built from a base
name, the name of the module in which they are defined (Top if in
coqtop), and possibly an arbitrary long sequence of directory (e.g.
"Coq.Lists.PolyList.flat\_map" where "Coq" means that "flat\_map" is part
of Coq standard library, "Lists" means it is defined in the Lists
library and "PolyList" means it is in the file Polylist) (+)

\item {} 
\sphinxAtStartPar
Constructions can be referred by their base name, or, in case of
conflict, by a "qualified" name, where the base name is prefixed
by the module name (and possibly by a directory name, and so
on). A fully qualified name is an absolute name which always refer
to the construction it denotes (to preserve the visibility of
all constructions, no conflict is allowed for an absolute name) (+)

\item {} 
\sphinxAtStartPar
Long names are available for modules with the possibility of using
the directory name as a component of the module full name (with
option \sphinxhyphen{}R to coqtop and coqc, or command Add LoadPath) (+)

\item {} 
\sphinxAtStartPar
Improved conflict resolution strategy (the Unix PATH model),
allowing more constructions to be referred just by their base name

\end{itemize}


\subparagraph{Language: miscellaneous}
\label{\detokenize{history:language-miscellaneous}}\begin{itemize}
\item {} 
\sphinxAtStartPar
The names of variables for Record projections \_and\_ for induction principles
(e.g. sum\_ind) is now based on the first letter of their type (main
source of incompatibility) (**)(+)

\item {} 
\sphinxAtStartPar
Most typing errors have now a precise location in the source (+)

\item {} 
\sphinxAtStartPar
Slightly different mechanism to solve "?" (*)(+)

\item {} 
\sphinxAtStartPar
More arguments may be considered implicit at section closing (*)(+)

\item {} 
\sphinxAtStartPar
Bug with identifiers ended by a number greater than 2\textasciicircum{}30 fixed (+)

\item {} 
\sphinxAtStartPar
New visibility discipline for Remark, Fact and Local: Remark's and
Fact's now survive at the end of section, but are only accessible using a
qualified names as soon as their strength expires; Local's disappear and
are moved into local definitions for each construction persistent at
section closing

\end{itemize}


\subparagraph{Language: Cases}
\label{\detokenize{history:language-cases}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Cases no longer considers aliases inferable from dependencies in types (*)(+)

\item {} 
\sphinxAtStartPar
A redundant clause in Cases is now an error (*)

\end{itemize}


\subparagraph{Reduction}
\label{\detokenize{history:reduction}}\begin{itemize}
\item {} 
\sphinxAtStartPar
New reduction flags "Zeta" and "Evar" in Eval Compute, for inlining of
local definitions and instantiation of existential variables

\item {} 
\sphinxAtStartPar
Delta reduction flag does not perform Zeta and Evar reduction any more (*)

\item {} 
\sphinxAtStartPar
Constants declared as opaque (using Qed) can no longer become
transparent (a constant intended to be alternatively opaque and
transparent must be declared as transparent (using Defined)); a risk
exists (until next Coq version) that Simpl and Hnf reduces opaque
constants (*)

\end{itemize}


\subparagraph{New tactics}
\label{\detokenize{history:new-tactics}}\begin{itemize}
\item {} 
\sphinxAtStartPar
New set of tactics to deal with types equipped with specific
equalities (a.k.a. Setoids, e.g. nat equipped with eq\_nat) {[}by C. Renard{]}

\item {} 
\sphinxAtStartPar
New tactic Assert, similar to Cut but expected to be more user\sphinxhyphen{}friendly

\item {} 
\sphinxAtStartPar
New tactic NewDestruct and NewInduction intended to replace Elim
and Induction, Case and Destruct in a more user\sphinxhyphen{}friendly way (see
restrictions in the reference manual)

\item {} 
\sphinxAtStartPar
New tactic ROmega: an experimental alternative (based on reflexion) to Omega
{[}by P. Crégut{]}

\item {} 
\sphinxAtStartPar
New tactic language Ltac (see reference manual) (+)

\item {} 
\sphinxAtStartPar
New versions of Tauto and Intuition, fully rewritten in the new Ltac
language; they run faster and produce more compact proofs; Tauto is
fully compatible but, in exchange of a better uniformity, Intuition
is slightly weaker (then use Tauto instead) (**)(+)

\item {} 
\sphinxAtStartPar
New tactic Field to decide equalities on commutative fields (as a
special case, it works on real numbers) (+)

\item {} 
\sphinxAtStartPar
New tactic Fourier to solve linear inequalities on reals numbers
{[}by L. Pottier{]} (+)

\item {} 
\sphinxAtStartPar
New tactics dedicated to real numbers: DiscrR, SplitRmult, SplitAbsolu (+)

\end{itemize}


\subparagraph{Changes in existing tactics}
\label{\detokenize{history:changes-in-existing-tactics}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Reduction tactics in local definitions apply only to the body

\item {} 
\sphinxAtStartPar
New syntax of the form "Compute in Type of H." to require a reduction on
the types of local definitions

\item {} 
\sphinxAtStartPar
Inversion, Injection, Discriminate, ... apply also on the
quantified premises of a goal (using the "Intros until" syntax)

\item {} 
\sphinxAtStartPar
Decompose has been fixed but hypotheses may get different names (*)(+)

\item {} 
\sphinxAtStartPar
Tauto now manages uniformly hypotheses and conclusions of the form
\sphinxcode{\sphinxupquote{t=t}} which all are considered equivalent to \sphinxcode{\sphinxupquote{True}}. Especially,
Tauto now solves goals of the form \sphinxcode{\sphinxupquote{H : \textasciitilde{} t = t |\sphinxhyphen{} A}}.

\item {} 
\sphinxAtStartPar
The "Let" tactic has been renamed "LetTac" and is now based on the
primitive "let\sphinxhyphen{}in" (+)

\item {} 
\sphinxAtStartPar
Elim can no longer be used with an elimination schema different from
the one defined at definition time of the inductive type. To overload
an elimination schema, use "Elim <hyp> using <name of the new schema>"
(*)(+)

\item {} 
\sphinxAtStartPar
Simpl no longer unfolds the recursive calls of a mutually defined
fixpoint (*)(+)

\item {} 
\sphinxAtStartPar
Intro now fails if the hypothesis name already exists (*)(+)

\item {} 
\sphinxAtStartPar
"Require Prolog" is no longer needed (i.e. it is available by default) (*)(+)

\item {} 
\sphinxAtStartPar
Unfold now fails on a non unfoldable identifier (*)(+)

\item {} 
\sphinxAtStartPar
Unfold also applies on definitions of the local context

\item {} 
\sphinxAtStartPar
AutoRewrite now deals only with the main goal and it is the purpose of
Hint Rewrite to deal with generated subgoals (+)

\item {} 
\sphinxAtStartPar
Redundant or incompatible instantiations in Apply ... with ... are now
correctly managed (+)

\end{itemize}


\subparagraph{Efficiency}
\label{\detokenize{history:efficiency}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Excessive memory uses specific to V7.0 fixed

\item {} 
\sphinxAtStartPar
Sizes of .vo files vary a lot compared to V6.3 (from \sphinxhyphen{}30\% to +300\%
depending on the developments)

\item {} 
\sphinxAtStartPar
An improved reduction strategy for lazy evaluation

\item {} 
\sphinxAtStartPar
A more economical mechanism to ensure logical consistency at the Type level;
warning: this is experimental and may produce "universes" anomalies
(please report)

\end{itemize}


\subparagraph{Concrete syntax of constructions}
\label{\detokenize{history:concrete-syntax-of-constructions}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Only identifiers starting with "\_" or a letter, and followed by letters,
digits, "\_" or "'" are allowed (e.g. "\$" and "@" are no longer allowed) (*)

\item {} 
\sphinxAtStartPar
A multiple binder like (a:A)(a,b:(P a))(Q a) is no longer parsed as
(a:A)(a0:(P a))(b:(P a))(Q a0) but as (a:A)(a0:(P a))(b:(P a0))(Q a0) (*)(+)

\item {} 
\sphinxAtStartPar
A dedicated syntax has been introduced for Reals (e.g \sphinxcode{\sphinxupquote{3+1/x}}) (+)

\item {} 
\sphinxAtStartPar
Pretty\sphinxhyphen{}printing of Infix notations fixed. (+)

\end{itemize}


\subparagraph{Parsing and grammar extension}
\label{\detokenize{history:parsing-and-grammar-extension}}\begin{itemize}
\item {} 
\sphinxAtStartPar
More constraints when writing ast
\begin{itemize}
\item {} 
\sphinxAtStartPar
"\{...\}" and the macros \$LIST, \$VAR, etc. now expect a metavariable
(an identifier starting with \$) (*)

\item {} \begin{description}
\item[{identifiers should starts with a letter or "\_" and be followed}] \leavevmode
\sphinxAtStartPar
by letters, digits, "\_" or "'" (other characters are still
supported but it is not advised to use them) (*)(+)

\end{description}

\end{itemize}

\item {} 
\sphinxAtStartPar
Entry "command" in "Grammar" and quotations (<<...>> stuff) is
renamed "constr" as in "Syntax" (+)

\item {} 
\sphinxAtStartPar
New syntax "{[}" sentence\_1 ... sentence\_n"{]}." to group sentences (useful
for Time and to write grammar rules abbreviating several commands) (+)

\item {} 
\sphinxAtStartPar
The default parser for actions in the grammar rules (and for
patterns in the pretty\sphinxhyphen{}printing rules) is now the one associated with
the grammar (i.e. vernac, tactic or constr); no need then for
quotations as in <:vernac:<...>>; to return an "ast", the grammar
must be explicitly typed with tag ": ast" or ": ast list", or if a
syntax rule, by using <<...>> in the patterns (expression inside
these angle brackets are parsed as "ast"); for grammars other than
vernac, tactic or constr, you may explicitly type the action with
tags ": constr", ": tactic", or ":vernac" (**)(+)

\item {} 
\sphinxAtStartPar
Interpretation of names in Grammar rule is now based on long names,
which allows to avoid problems (or sometimes tricks;) related to
overloaded names (+)

\end{itemize}


\subparagraph{New commands}
\label{\detokenize{history:new-commands}}\begin{itemize}
\item {} 
\sphinxAtStartPar
New commands "Print XML All", "Show XML Proof", ... to show or
export theories to XML to be used with Helm's publishing and rendering
tools (see \sphinxurl{http://www.cs.unibo.it/helm}) (by Claudio Sacerdoti Coen) (+)

\item {} 
\sphinxAtStartPar
New commands to manually set implicit arguments (+)
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Implicits ident." to activate the implicit arguments mode just for ident

\item {} \begin{description}
\item[{"Implicits ident {[}num1 num2 ...{]}." to explicitly give which}] \leavevmode
\sphinxAtStartPar
arguments have to be considered as implicit

\end{description}

\end{itemize}

\item {} 
\sphinxAtStartPar
New SearchPattern/SearchRewrite (by Yves Bertot) (+)

\item {} 
\sphinxAtStartPar
New commands "Debug on"/"Debug off" to activate/deactivate the tactic
language debugger (+)

\item {} 
\sphinxAtStartPar
New commands to map physical paths to logical paths (+)
\sphinxhyphen{} Add LoadPath physical\_dir as logical\_dir
\sphinxhyphen{} Add Rec LoadPath physical\_dir as logical\_dir

\end{itemize}


\subparagraph{Changes in existing commands}
\label{\detokenize{history:changes-in-existing-commands}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Generalization of the usage of qualified identifiers in tactics
and commands about globals, e.g. Decompose, Eval Delta;
Hints Unfold, Transparent, Require

\item {} 
\sphinxAtStartPar
Require synchronous with Reset; Require's scope stops at Section ending (*)

\item {} 
\sphinxAtStartPar
For a module indirectly loaded by a "Require" but not exported,
the command "Import module" turns the constructions defined in the
module accessible by their short name, and activates the Grammar,
Syntax, Hint, ... declared in the module (+)

\item {} 
\sphinxAtStartPar
The scope of the "Search" command can be restricted to some modules (+)

\item {} 
\sphinxAtStartPar
Final dot in command (full stop/period) must be followed by a blank
(newline, tabulation or whitespace) (+)

\item {} 
\sphinxAtStartPar
Slight restriction of the syntax for Cbv Delta: if present, option {[}\sphinxhyphen{}myconst{]}
must immediately follow the Delta keyword (*)(+)

\item {} 
\sphinxAtStartPar
SearchIsos currently not supported

\item {} 
\sphinxAtStartPar
Add ML Path is now implied by Add LoadPath (+)

\item {} 
\sphinxAtStartPar
New names for the following commands (+)

\sphinxAtStartPar
AddPath \sphinxhyphen{}> Add LoadPath
Print LoadPath \sphinxhyphen{}> Print LoadPath
DelPath \sphinxhyphen{}> Remove LoadPath
AddRecPath \sphinxhyphen{}> Add Rec LoadPath
Print Path \sphinxhyphen{}> Print Coercion Paths

\sphinxAtStartPar
Implicit Arguments On \sphinxhyphen{}> Set Implicit Arguments
Implicit Arguments Off \sphinxhyphen{}> Unset Implicit Arguments

\sphinxAtStartPar
Begin Silent \sphinxhyphen{}> Set Silent
End Silent \sphinxhyphen{}> Unset Silent.

\end{itemize}


\subparagraph{Tools}
\label{\detokenize{history:tools}}\begin{itemize}
\item {} 
\sphinxAtStartPar
coqtop (+)
\begin{itemize}
\item {} 
\sphinxAtStartPar
Two executables: coqtop.byte and coqtop.opt (if supported by the platform)

\item {} 
\sphinxAtStartPar
coqtop is a link to the more efficient executable (coqtop.opt if present)

\item {} 
\sphinxAtStartPar
option \sphinxhyphen{}full is obsolete (+)

\end{itemize}

\item {} 
\sphinxAtStartPar
do\_Makefile renamed into coq\_makefile (+)

\item {} 
\sphinxAtStartPar
New option \sphinxhyphen{}R to coqtop and coqc to map a physical directory to a logical
one (+)

\item {} 
\sphinxAtStartPar
coqc no longer needs to create a temporary file

\item {} 
\sphinxAtStartPar
No more warning if no initialization file .coqrc exists

\end{itemize}


\subparagraph{Extraction}
\label{\detokenize{history:extraction}}\begin{itemize}
\item {} 
\sphinxAtStartPar
New algorithm for extraction able to deal with "Type" (+)
(by J.\sphinxhyphen{}C. Filliâtre and P. Letouzey)

\end{itemize}


\subparagraph{Standard library}
\label{\detokenize{history:standard-library}}\begin{itemize}
\item {} 
\sphinxAtStartPar
New library on maps on integers (IntMap, contributed by Jean Goubault)

\item {} 
\sphinxAtStartPar
New lemmas about integer numbers {[}ZArith{]}

\item {} 
\sphinxAtStartPar
New lemmas and a "natural" syntax for reals {[}Reals{]} (+)

\item {} 
\sphinxAtStartPar
Exc/Error/Value renamed into Option/Some/None (*)

\end{itemize}


\subparagraph{New user contributions}
\label{\detokenize{history:new-user-contributions}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Constructive complex analysis and the Fundamental Theorem of Algebra {[}FTA{]}
(Herman Geuvers, Freek Wiedijk, Jan Zwanenburg, Randy Pollack,
Henk Barendregt, Nijmegen)

\item {} 
\sphinxAtStartPar
A new axiomatization of ZFC set theory {[}Functions\_in\_ZFC{]}
(C. Simpson, Sophia\sphinxhyphen{}Antipolis)

\item {} 
\sphinxAtStartPar
Basic notions of graph theory {[}GRAPHS\sphinxhyphen{}BASICS{]} (Jean Duprat, Lyon)

\item {} 
\sphinxAtStartPar
A library for floating\sphinxhyphen{}point numbers {[}Float{]} (Laurent Théry, Sylvie Boldo,
Sophia\sphinxhyphen{}Antipolis)

\item {} 
\sphinxAtStartPar
Formalisation of CTL and TCTL temporal logic {[}CtlTctl{]} (Carlos
Daniel Luna,Montevideo)

\item {} 
\sphinxAtStartPar
Specification and verification of the Railroad Crossing Problem
in CTL and TCTL {[}RailroadCrossing{]} (Carlos Daniel Luna,Montevideo)

\item {} 
\sphinxAtStartPar
P\sphinxhyphen{}automaton and the ABR algorithm {[}PAutomata{]}
(Christine Paulin, Emmanuel Freund, Orsay)

\item {} 
\sphinxAtStartPar
Semantics of a subset of the C language {[}MiniC{]}
(Eduardo Giménez, Emmanuel Ledinot, Suresnes)

\item {} 
\sphinxAtStartPar
Correctness proofs of the following imperative algorithms:
Bresenham line drawing algorithm {[}Bresenham{]}, Marché's minimal edition
distance algorithm {[}Diff{]} (Jean\sphinxhyphen{}Christophe Filliâtre, Orsay)

\item {} 
\sphinxAtStartPar
Correctness proofs of Buchberger's algorithm {[}Buchberger{]} and RSA
cryptographic algorithm {[}Rsa{]} (Laurent Théry, Sophia\sphinxhyphen{}Antipolis)

\item {} 
\sphinxAtStartPar
Correctness proof of Stalmarck tautology checker algorithm
{[}Stalmarck{]} (Laurent Théry, Pierre Letouzey, Sophia\sphinxhyphen{}Antipolis)

\end{itemize}


\paragraph{Details of changes in 7.2}
\label{\detokenize{history:details-of-changes-in-7-2}}
\sphinxAtStartPar
Language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Automatic insertion of patterns for local definitions in the type of
the constructors of an inductive types (for compatibility with V6.3
let\sphinxhyphen{}in style)

\item {} 
\sphinxAtStartPar
Coercions allowed in Cases patterns

\item {} 
\sphinxAtStartPar
New declaration "Canonical Structure id = t : I" to help resolution of
equations of the form (proj ?)=a; if proj(e)=a then a is canonically
equipped with the remaining fields in e, i.e. ? is instantiated by e

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New tactic "ClearBody H" to clear the body of definitions in local context

\item {} 
\sphinxAtStartPar
New tactic "Assert H := c" for forward reasoning

\item {} 
\sphinxAtStartPar
Slight improvement in naming strategy for NewInduction/NewDestruct

\item {} 
\sphinxAtStartPar
Intuition/Tauto do not perform useless unfolding and work up to conversion

\end{itemize}

\sphinxAtStartPar
Extraction (details in plugins/extraction/CHANGES or documentation)
\begin{itemize}
\item {} 
\sphinxAtStartPar
Syntax changes: there are no more options inside the extraction commands.
New commands for customization and options have been introduced instead.

\item {} 
\sphinxAtStartPar
More optimizations on extracted code.

\item {} 
\sphinxAtStartPar
Extraction tests are now embedded in 14 user contributions.

\end{itemize}

\sphinxAtStartPar
Standard library
\begin{itemize}
\item {} 
\sphinxAtStartPar
In {[}Relations{]}, Rstar.v and Newman.v now axiom\sphinxhyphen{}free.

\item {} 
\sphinxAtStartPar
In {[}Sets{]}, Integers.v now based on nat

\item {} 
\sphinxAtStartPar
In {[}Arith{]}, more lemmas in Min.v, new file Max.v, tail\sphinxhyphen{}recursive
plus and mult added to Plus.v and Mult.v respectively

\item {} 
\sphinxAtStartPar
New directory {[}Sorting{]} with a proof of heapsort (dragged from 6.3.1 lib)

\item {} 
\sphinxAtStartPar
In {[}Reals{]}, more lemmas in Rbase.v, new lemmas on square, square root and
trigonometric functions (R\_sqr.v \sphinxhyphen{} Rtrigo.v); a complementary approach
and new theorems about continuity and derivability in Ranalysis.v;  some
properties in plane geometry such as translation, rotation or similarity
in Rgeom.v; finite sums and Chasles property in Rsigma.v

\end{itemize}

\sphinxAtStartPar
Bugs
\begin{itemize}
\item {} 
\sphinxAtStartPar
Confusion between implicit args of locals and globals of same base name fixed

\item {} 
\sphinxAtStartPar
Various incompatibilities wrt inference of "?" in V6.3.1 fixed

\item {} 
\sphinxAtStartPar
Implicits in infix section variables bug fixed

\item {} 
\sphinxAtStartPar
Known coercions bugs fixed

\item {} 
\sphinxAtStartPar
Apply "universe anomaly" bug fixed

\item {} 
\sphinxAtStartPar
NatRing now working

\item {} 
\sphinxAtStartPar
"Discriminate 1", "Injection 1", "Simplify\_eq 1" now working

\item {} 
\sphinxAtStartPar
NewInduction bugs with let\sphinxhyphen{}in and recursively dependent hypotheses fixed

\item {} 
\sphinxAtStartPar
Syntax {[}x:=t:T{]}u now allowed as mentioned in documentation

\item {} 
\sphinxAtStartPar
Bug with recursive inductive types involving let\sphinxhyphen{}in fixed

\item {} 
\sphinxAtStartPar
Known pattern\sphinxhyphen{}matching bugs fixed

\item {} 
\sphinxAtStartPar
Known Cases elimination predicate bugs fixed

\item {} 
\sphinxAtStartPar
Improved errors messages for pattern\sphinxhyphen{}matching and projections

\item {} 
\sphinxAtStartPar
Better error messages for ill\sphinxhyphen{}typed Cases expressions

\end{itemize}

\sphinxAtStartPar
Incompatibilities
\begin{itemize}
\item {} 
\sphinxAtStartPar
New naming strategy for NewInduction/NewDestruct may affect 7.1 compatibility

\item {} 
\sphinxAtStartPar
Extra parentheses may exceptionally be needed in tactic definitions.

\item {} 
\sphinxAtStartPar
Coq extensions written in OCaml need to be updated (see dev/changements.txt
for a description of the main changes in the interface files of V7.2)

\item {} 
\sphinxAtStartPar
New behaviour of Intuition/Tauto may exceptionally lead to incompatibilities

\end{itemize}


\paragraph{Details of changes in 7.3}
\label{\detokenize{history:details-of-changes-in-7-3}}
\sphinxAtStartPar
Language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Slightly improved compilation of pattern\sphinxhyphen{}matching (slight source of
incompatibilities)

\item {} 
\sphinxAtStartPar
Record's now accept anonymous fields "\_" which does not build projections

\item {} 
\sphinxAtStartPar
Changes in the allowed elimination sorts for certain class of inductive
definitions : an inductive definition without constructors
of Sort Prop can be eliminated on sorts Set and Type A "singleton"
inductive definition (one constructor with arguments in the sort Prop
like conjunction of two propositions or equality) can be eliminated
directly on sort Type (In V7.2, only the sorts Prop and Set were allowed)

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New tactic "Rename x into y" for renaming hypotheses

\item {} 
\sphinxAtStartPar
New tactics "Pose x:=u" and "Pose u" to add definitions to local context

\item {} 
\sphinxAtStartPar
Pattern now working on partially applied subterms

\item {} 
\sphinxAtStartPar
Ring no longer applies irreversible congruence laws of mult but
better applies congruence laws of plus (slight source of incompatibilities).

\item {} 
\sphinxAtStartPar
Field now accepts terms to be simplified as arguments (as for Ring). This
extension has been also implemented using the toplevel tactic language.

\item {} 
\sphinxAtStartPar
Intuition does no longer unfold constants except "<\sphinxhyphen{}>" and "\textasciitilde{}". It
can be parameterized by a tactic. It also can introduce dependent
product if needed (source of incompatibilities)

\item {} 
\sphinxAtStartPar
"Match Context" now matching more recent hypotheses first and failing only
on user errors and Fail tactic (possible source of incompatibilities)

\item {} 
\sphinxAtStartPar
Tactic Definition's without arguments now allowed in Coq states

\item {} 
\sphinxAtStartPar
Better simplification and discrimination made by Inversion (source
of incompatibilities)

\end{itemize}

\sphinxAtStartPar
Bugs
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Intros H" now working like "Intro H" trying first to reduce if not a product

\item {} 
\sphinxAtStartPar
Forward dependencies in Cases now taken into account

\item {} 
\sphinxAtStartPar
Known bugs related to Inversion and let\sphinxhyphen{}in's fixed

\item {} 
\sphinxAtStartPar
Bug unexpected Delta with let\sphinxhyphen{}in now fixed

\end{itemize}

\sphinxAtStartPar
Extraction (details in plugins/extraction/CHANGES or documentation)
\begin{itemize}
\item {} 
\sphinxAtStartPar
Signatures of extracted terms are now mostly expunged from dummy arguments.

\item {} 
\sphinxAtStartPar
Haskell extraction is now operational (tested \& debugged).

\end{itemize}

\sphinxAtStartPar
Standard library
\begin{itemize}
\item {} 
\sphinxAtStartPar
Some additions in {[}ZArith{]}: three files (Zcomplements.v, Zpower.v
and Zlogarithms.v) moved from plugins/omega in order to be more
visible, one Zsgn function, more induction principles (Wf\_Z.v and
tail of Zcomplements.v), one more general Euclid theorem

\item {} 
\sphinxAtStartPar
Peano\_dec.v and Compare\_dec.v now part of Arith.v

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
new option \sphinxhyphen{}dump\sphinxhyphen{}glob to coqtop to dump globalizations (to be used by the
new documentation tool coqdoc; see \sphinxurl{http://www.lri.fr/~filliatr/coqdoc})

\end{itemize}

\sphinxAtStartPar
User Contributions
\begin{itemize}
\item {} 
\sphinxAtStartPar
CongruenceClosure (congruence closure decision procedure)
{[}Pierre Corbineau, ENS Cachan{]}

\item {} 
\sphinxAtStartPar
MapleMode (an interface to embed Maple simplification procedures over
rational fractions in Coq)
{[}David Delahaye, Micaela Mayero, Chalmers University{]}

\item {} 
\sphinxAtStartPar
Presburger: A formalization of Presburger's algorithm
{[}Laurent Thery, INRIA Sophia Antipolis{]}

\item {} 
\sphinxAtStartPar
Chinese has been rewritten using Z from ZArith as datatype
ZChinese is the new version, Chinese the obsolete one
{[}Pierre Letouzey, LRI Orsay{]}

\end{itemize}

\sphinxAtStartPar
Incompatibilities
\begin{itemize}
\item {} 
\sphinxAtStartPar
Ring: exceptional incompatibilities (1 above 650 in submitted user
contribs, leading to a simplification)

\item {} 
\sphinxAtStartPar
Intuition: does not unfold any definition except "<\sphinxhyphen{}>" and "\textasciitilde{}"

\item {} 
\sphinxAtStartPar
Cases: removal of some extra Cases in configurations of the form
"Cases ... of C \_ => ... | \_ D => ..."  (effects on 2 definitions of
submitted user contributions necessitating the removal of now superfluous
proof steps in 3 different proofs)

\item {} 
\sphinxAtStartPar
Match Context, in case of incompatibilities because of a now non
trapped error (e.g. Not\_found or Failure), use instead tactic Fail
to force Match Context trying the next clause

\item {} 
\sphinxAtStartPar
Inversion: better simplification and discrimination may occasionally
lead to less subgoals and/or hypotheses and different naming of hypotheses

\item {} 
\sphinxAtStartPar
Unification done by Apply/Elim has been changed and may exceptionally lead
to incompatible instantiations

\item {} 
\sphinxAtStartPar
Peano\_dec.v and Compare\_dec.v parts of Arith.v make Auto more
powerful if these files were not already required (1 occurrence of
this in submitted user contribs)

\end{itemize}


\subparagraph{Changes in 7.3.1}
\label{\detokenize{history:changes-in-7-3-1}}
\sphinxAtStartPar
Bug fixes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Corrupted Field tactic and Match Context tactic construction fixed

\item {} 
\sphinxAtStartPar
Checking of names already existing in Assert added (\#1386)

\item {} 
\sphinxAtStartPar
Invalid argument bug in Exact tactic solved (\#1387)

\item {} 
\sphinxAtStartPar
Colliding bound names bug fixed (\#1412)

\item {} 
\sphinxAtStartPar
Wrong non\sphinxhyphen{}recursivity test for Record fixed (\#1394)

\item {} 
\sphinxAtStartPar
Out of memory/seg fault bug related to parametric inductive fixed (\#1404)

\item {} 
\sphinxAtStartPar
Setoid\_replace/Setoid\_rewrite bug wrt "==" fixed

\end{itemize}

\sphinxAtStartPar
Misc
\begin{itemize}
\item {} 
\sphinxAtStartPar
Ocaml version >= 3.06 is needed to compile Coq from sources

\item {} 
\sphinxAtStartPar
Simplification of fresh names creation strategy for Assert, Pose and
LetTac (\#1402)

\end{itemize}


\paragraph{Details of changes in 7.4}
\label{\detokenize{history:details-of-changes-in-7-4}}
\sphinxAtStartPar
Symbolic notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
Introduction of a notion of scope gathering notations in a consistent set;
a notation sets has been developed for nat, Z and R (undocumented)

\item {} 
\sphinxAtStartPar
New command "Notation" for declaring notations simultaneously for
parsing and printing (see chap 10 of the reference manual)

\item {} 
\sphinxAtStartPar
Declarations with only implicit arguments now handled (e.g. the
argument of nil can be set implicit; use !nil to refer to nil
without arguments)

\item {} 
\sphinxAtStartPar
"Print Scope sc" and "Locate ntn" allows to know to what expression a
notation is bound

\item {} 
\sphinxAtStartPar
New defensive strategy for printing or not implicit arguments to ensure
re\sphinxhyphen{}type\sphinxhyphen{}checkability of the printed term

\item {} 
\sphinxAtStartPar
In Grammar command, the only predefined non\sphinxhyphen{}terminal entries are ident,
global, constr and pattern (e.g. nvar, numarg disappears); the only
allowed grammar types are constr and pattern; ast and ast list are no
longer supported; some incompatibilities in Grammar: when a syntax is a
initial segment of an other one,  Grammar does not work, use Notation

\end{itemize}

\sphinxAtStartPar
Library
\begin{itemize}
\item {} 
\sphinxAtStartPar
Lemmas in Set from Compare\_dec.v (le\_lt\_dec, ...) and Wf\_nat.v
(lt\_wf\_rec, ...) are now transparent. This may be source of
incompatibilities.

\item {} 
\sphinxAtStartPar
Syntactic Definitions Fst, Snd, Ex, All, Ex2, AllT, ExT, ExT2,
ProjS1, ProjS2, Error, Value and Except are turned to
notations. They now must be applied (incompatibilities only in
unrealistic cases).

\item {} 
\sphinxAtStartPar
More efficient versions of Zmult and times (30\% faster)

\item {} 
\sphinxAtStartPar
Reals: the library is now divided in 6 parts (Rbase, Rfunctions,
SeqSeries, Rtrigo, Ranalysis, Integration). New tactics: Sup and
RCompute. See Reals.v for details.

\end{itemize}

\sphinxAtStartPar
Modules
\begin{itemize}
\item {} 
\sphinxAtStartPar
Beta version, see doc chap 2.5 for commands and chap 5 for theory

\end{itemize}

\sphinxAtStartPar
Language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Inductive definitions now accept ">" in constructor types to declare
the corresponding constructor as a coercion.

\item {} 
\sphinxAtStartPar
Idem for assumptions declarations and constants when the type is mentioned.

\item {} 
\sphinxAtStartPar
The "Coercion" and "Canonical Structure" keywords now accept the
same syntax as "Definition", i.e. "hyps :=c (:t)?" or "hyps :t".

\item {} 
\sphinxAtStartPar
Theorem\sphinxhyphen{}like declaration now accepts the syntax "Theorem thm {[}x:t;...{]} : u".

\item {} 
\sphinxAtStartPar
Remark's and Fact's now definitively behave as Theorem and Lemma: when
sections are closed, the full name of a Remark or a Fact has no longer a
section part (source of incompatibilities)

\item {} 
\sphinxAtStartPar
Opaque Local's (i.e. built by tactics and ended by Qed), do not
survive section closing any longer; as a side\sphinxhyphen{}effect, Opaque Local's
now appear in the local context of proofs; their body is hidden
though (source of incompatibilities); use one of Remark/Fact/Lemma/Theorem
instead to simulate the old behaviour of Local (the section part of
the name is not kept though)

\end{itemize}

\sphinxAtStartPar
ML tactics and commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Grammar tactic" and "Grammar vernac" of type "ast" are no longer
supported (only "Grammar tactic simple\_tactic" of type "tactic"
remains available).

\item {} 
\sphinxAtStartPar
Concrete syntax for ML written commands and tactics is
now declared at ML level using camlp4 macros TACTIC EXTEND et VERNAC
COMMAND EXTEND.

\item {} 
\sphinxAtStartPar
"Check n c" now "n:Check c", "Eval n ..." now "n:Eval ..."

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Proof with T}} (no documentation)

\item {} 
\sphinxAtStartPar
SearchAbout id \sphinxhyphen{} prints all theorems which contain id in their type

\end{itemize}

\sphinxAtStartPar
Tactic definitions
\begin{itemize}
\item {} 
\sphinxAtStartPar
Static globalisation of identifiers and global references (source of
incompatibilities, especially, Recursive keyword is required for
mutually recursive definitions).

\item {} 
\sphinxAtStartPar
New evaluation semantics: no more partial evaluation at definition time;
evaluation of all Tactic/Meta Definition, even producing terms, expect
a proof context to be evaluated (especially "()" is no longer needed).

\item {} 
\sphinxAtStartPar
Debugger now shows the nesting level and the reasons of failure

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Equality tactics (Rewrite, Reflexivity, Symmetry, Transitivity) now
understand JM equality

\item {} 
\sphinxAtStartPar
Simpl and Change now apply to subterms also

\item {} 
\sphinxAtStartPar
"Simpl f" reduces subterms whose head constant is f

\item {} 
\sphinxAtStartPar
Double Induction now referring to hypotheses like "Intros until"

\item {} 
\sphinxAtStartPar
"Inversion" now applies also on quantified hypotheses (naming as
for Intros until)

\item {} 
\sphinxAtStartPar
NewDestruct now accepts terms with missing hypotheses

\item {} 
\sphinxAtStartPar
NewDestruct and NewInduction now accept user\sphinxhyphen{}provided elimination scheme

\item {} 
\sphinxAtStartPar
NewDestruct and NewInduction now accept user\sphinxhyphen{}provided introduction names

\item {} 
\sphinxAtStartPar
Omega could solve goals such as \sphinxcode{\sphinxupquote{\textasciitilde{}x<y |\sphinxhyphen{} x>=y}} but failed when the
hypothesis was unfolded to \sphinxcode{\sphinxupquote{x < y \sphinxhyphen{}> False}}. This is fixed. In addition,
it can also recognize 'False' in the hypothesis and use it to solve the
goal.

\item {} 
\sphinxAtStartPar
Coercions now handled in "with" bindings

\item {} 
\sphinxAtStartPar
"Subst x" replaces all occurrences of x by t in the goal and hypotheses
when an hypothesis x=t or x:=t or t=x exists

\item {} 
\sphinxAtStartPar
Fresh names for Assert and Pose now based on collision\sphinxhyphen{}avoiding
Intro naming strategy (exceptional source of incompatibilities)

\item {} 
\sphinxAtStartPar
LinearIntuition (no documentation)

\item {} 
\sphinxAtStartPar
Unfold expects a correct evaluable argument

\item {} 
\sphinxAtStartPar
Clear expects existing hypotheses

\end{itemize}

\sphinxAtStartPar
Extraction (See details in plugins/extraction/CHANGES and README):
\begin{itemize}
\item {} 
\sphinxAtStartPar
An experimental Scheme extraction is provided.

\item {} 
\sphinxAtStartPar
Concerning OCaml, extracted code is now ensured to always type check,
thanks to automatic inserting of Obj.magic.

\item {} 
\sphinxAtStartPar
Experimental extraction of Coq new modules to Ocaml modules.

\end{itemize}

\sphinxAtStartPar
Proof rendering in natural language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Export of theories to XML for publishing and rendering purposes now
includes proof\sphinxhyphen{}trees (see \sphinxurl{http://www.cs.unibo.it/helm})

\end{itemize}

\sphinxAtStartPar
Miscellaneous
\begin{itemize}
\item {} 
\sphinxAtStartPar
Printing Coercion now used through the standard keywords Set/Add, Test, Print

\item {} 
\sphinxAtStartPar
"Print Term id" is an alias for "Print id"

\item {} 
\sphinxAtStartPar
New switch "Unset/Set Printing Symbols" to control printing of
symbolic notations

\item {} 
\sphinxAtStartPar
Two new variants of implicit arguments are available
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Unset}}/\sphinxcode{\sphinxupquote{Set Contextual Implicits}} tells to consider implicit also the
arguments inferable from the context (e.g. for nil or refl\_eq)

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Unset}}/\sphinxcode{\sphinxupquote{Set Strict Implicits}} tells to consider implicit only the
arguments that are inferable in any case (i.e. arguments that occurs
as argument of rigid constants in the type of the remaining arguments;
e.g. the witness of an existential is not strict since it can vanish when
applied to a predicate which does not use its argument)

\end{itemize}

\end{itemize}

\sphinxAtStartPar
Incompatibilities
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Grammar tactic ... : ast" and "Grammar vernac ... : ast" are no
longer supported, use TACTIC EXTEND and VERNAC COMMAND EXTEND on the
ML\sphinxhyphen{}side instead

\item {} 
\sphinxAtStartPar
Transparency of le\_lt\_dec and co (leads to some simplification in
proofs; in some cases, incompatibilites is solved by declaring locally
opaque the relevant constant)

\item {} 
\sphinxAtStartPar
Opaque Local do not now survive section closing (rename them into
Remark/Lemma/... to get them still surviving the sections; this
renaming allows also to solve incompatibilites related to now
forbidden calls to the tactic Clear)

\item {} 
\sphinxAtStartPar
Remark and Fact have no longer (very) long names (use Local instead in case
of name conflict)

\end{itemize}

\sphinxAtStartPar
Bugs
\begin{itemize}
\item {} 
\sphinxAtStartPar
Improved localisation of errors in Syntactic Definitions

\item {} 
\sphinxAtStartPar
Induction principle creation failure in presence of let\sphinxhyphen{}in fixed (\#1459)

\item {} 
\sphinxAtStartPar
Inversion bugs fixed (\#1427 and \#1437)

\item {} 
\sphinxAtStartPar
Omega bug related to Set fixed (\#1384)

\item {} 
\sphinxAtStartPar
Type\sphinxhyphen{}checking inefficiency of nested destructuring let\sphinxhyphen{}in fixed (\#1435)

\item {} 
\sphinxAtStartPar
Improved handling of let\sphinxhyphen{}in during holes resolution phase (\#1460)

\end{itemize}

\sphinxAtStartPar
Efficiency
\begin{itemize}
\item {} 
\sphinxAtStartPar
Implementation of a memory sharing strategy reducing memory
requirements by an average ratio of 3.

\end{itemize}


\subsection{Recent changes}
\label{\detokenize{changes:recent-changes}}\label{\detokenize{changes:changes}}\label{\detokenize{changes::doc}}

\subsubsection{Version 8.14}
\label{\detokenize{changes:version-8-14}}

\paragraph{Summary of changes}
\label{\detokenize{changes:summary-of-changes}}
\sphinxAtStartPar
Coq version 8.14 integrates many usability improvements, as well
as an important change in the core language. The main changes include:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The {\hyperref[\detokenize{changes:caserepresentation}]{\sphinxcrossref{\DUrole{std,std-ref}{internal representation}}}} of \sphinxcode{\sphinxupquote{match}} has changed
to a more space\sphinxhyphen{}efficient and cleaner structure, allowing the fix of a completeness
issue with cumulative inductive types in the type\sphinxhyphen{}checker.
The internal representation is now closer to the user\sphinxhyphen{}level view of \sphinxcode{\sphinxupquote{match}},
where the argument context of branches and the inductive binders \sphinxcode{\sphinxupquote{in}} and \sphinxcode{\sphinxupquote{as}}
do not carry type annotations.

\item {} 
\sphinxAtStartPar
A {\hyperref[\detokenize{changes:coqnative}]{\sphinxcrossref{\DUrole{std,std-ref}{new}}}} \sphinxcode{\sphinxupquote{coqnative}} binary performs separate native compilation
of libraries, starting from a \sphinxcode{\sphinxupquote{.vo}} file. It is supported by \sphinxcode{\sphinxupquote{coq\_makefile}}.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{changes:tccanon}]{\sphinxcrossref{\DUrole{std,std-ref}{Improvements}}}} to typeclasses and canonical structure
resolution, allowing more terms to be considered as classes or keys.

\item {} 
\sphinxAtStartPar
More control over {\hyperref[\detokenize{changes:id20}]{\sphinxcrossref{\DUrole{std,std-ref}{notations}}}} declarations and support
for primitive types in string and number notations.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{changes:id37}]{\sphinxcrossref{\DUrole{std,std-ref}{Removal}}}} of deprecated tactics, notably \sphinxcode{\sphinxupquote{omega}}, which has
been replaced by a greatly improved \sphinxcode{\sphinxupquote{lia}}, along with many bug fixes.

\item {} 
\sphinxAtStartPar
New  {\hyperref[\detokenize{changes:ltac2}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac2}}}} APIs for interaction with Ltac1, manipulation of
inductive types and printing.

\item {} 
\sphinxAtStartPar
Many {\hyperref[\detokenize{changes:stdlib}]{\sphinxcrossref{\DUrole{std,std-ref}{changes and additions}}}} to the standard library in the numbers,
vectors and lists libraries. A new signed primitive integers library \sphinxcode{\sphinxupquote{Sint63}}
is available in addition to the unsigned \sphinxcode{\sphinxupquote{Uint63}} library.

\end{itemize}

\sphinxAtStartPar
See the {\hyperref[\detokenize{changes:changes-in-8-14-0}]{\sphinxcrossref{Changes in 8.14.0}}} section below for the detailed list of changes,
including potentially breaking changes marked with \sphinxstylestrong{Changed}.
Coq's \sphinxhref{https://coq.github.io/doc/v8.14/refman}{reference manual}%
\begin{footnote}[66]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.github.io/doc/v8.14/refman}
%
\end{footnote},
\sphinxhref{https://coq.github.io/doc/v8.14/stdlib}{documentation of the standard library}%
\begin{footnote}[67]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.github.io/doc/v8.14/stdlib}
%
\end{footnote}
and \sphinxhref{https://coq.github.io/doc/v8.14/api}{developer documentation of the ML API}%
\begin{footnote}[68]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.github.io/doc/v8.14/api}
%
\end{footnote}
are also available.

\sphinxAtStartPar
Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop and Théo Zimmermann worked on maintaining and improving the
continuous integration system and package building infrastructure.

\sphinxAtStartPar
Erik Martin\sphinxhyphen{}Dorel has maintained the \sphinxhref{https://hub.docker.com/r/coqorg/coq}{Coq Docker images}%
\begin{footnote}[69]\sphinxAtStartFootnote
\sphinxnolinkurl{https://hub.docker.com/r/coqorg/coq}
%
\end{footnote} that are used in many Coq
projects for continuous integration.

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

\sphinxAtStartPar
The \sphinxhref{https://github.com/coq/platform}{Coq Platform}%
\begin{footnote}[70]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/platform}
%
\end{footnote} has been maintained
by Michael Soegtrop and Enrico Tassi.

\sphinxAtStartPar
Our current maintainers are Yves Bertot, Frédéric Besson, Ali Caglayan, Tej
Chajed, Cyril Cohen, Pierre Corbineau, Pierre Courtieu, Maxime Dénès,
Jim Fehrle, Julien Forest, Emilio Jesús Gallego Arias, Gaëtan Gilbert,
Georges Gonthier, Benjamin Grégoire, Jason Gross, Hugo Herbelin,
Vincent Laporte, Olivier Laurent, Assia Mahboubi, Kenji Maillard,
Guillaume Melquiond, Pierre\sphinxhyphen{}Marie Pédrot, Clément Pit\sphinxhyphen{}Claudel, Pierre Roux,
Kazuhiko Sakaguchi, Vincent Semeria, Michael Soegtrop, Arnaud Spiwack,
Matthieu Sozeau, Enrico Tassi, Laurent Théry, Anton Trunov, Li\sphinxhyphen{}yao Xia
and Théo Zimmermann. See the \sphinxhref{https://coq.inria.fr/coq-team.html}{Coq Team face book}%
\begin{footnote}[71]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.inria.fr/coq-team.html}
%
\end{footnote}
page for more details.

\sphinxAtStartPar
The 54 contributors to this version are Reynald Affeldt,
Arthur Azevedo de Amorim, Yves Bertot, Frédéric Besson, Lasse Blaauwbroek, Ana Borges,
Ali Caglayan, Cyril Cohen,  Columbus240, Pierre Courtieu, Maxime Dénès, Andrej Dudenhefner,
Jim Fehrle, Yannick Forster,  Simon Friis Vindum, Gaëtan Gilbert, Jason Gross, Samuel Gruetter, Stefan Haan,
Hugo Herbelin, Jasper Hugunin, Emilio Jesús Gallego Arias, Jacques\sphinxhyphen{}Henri Jourdan,
Ralf Jung, Jan\sphinxhyphen{}Oliver Kaiser, Fabian Kunze, Vincent Laporte, Olivier Laurent,
Yishuai Li, Barry M. Trager, Kenji Maillard, Erik Martin\sphinxhyphen{}Dorel, Guillaume Melquiond,
Isaac Oscar Gariano, Pierre\sphinxhyphen{}Marie Pédrot, Rudy Peterson, Clément Pit\sphinxhyphen{}Claudel, Pierre Roux,
Takafumi Saikawa, Kazuhiko Sakaguchi, Gabriel Scherer, Vincent Semeria, shenlebantongying,
Avi Shinnar, slrnsc, Michael Soegtrop, Matthieu Sozeau, Enrico Tassi, Hendrik Tews, Anton Trunov,
Karolin Varner, Li\sphinxhyphen{}yao Xia, Beta Ziliani and Théo Zimmermann.

\sphinxAtStartPar
The Coq community at large helped improve the design of this new version via
the GitHub issue and pull request system, the Coq development mailing list
\sphinxhref{mailto:coqdev@inria.fr}{coqdev@inria.fr}, the \sphinxhref{mailto:coq-club@inria.fr}{coq\sphinxhyphen{}club@inria.fr} mailing list, the \sphinxhref{https://coq.discourse.group/}{Discourse forum}%
\begin{footnote}[72]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.discourse.group/}
%
\end{footnote} and the \sphinxhref{http://coq.zulipchat.com}{Coq Zulip chat}%
\begin{footnote}[73]\sphinxAtStartFootnote
\sphinxnolinkurl{http://coq.zulipchat.com}
%
\end{footnote}.

\sphinxAtStartPar
Version 8.14's development spanned 9 months from the release of
Coq 8.13.0. Guillaume Melquiond is the release manager of Coq 8.14.
This release is the result of 522 merged PRs, closing \textasciitilde{}150 issues.

\begin{DUlineblock}{0em}
\item[] Nantes, September 2021,
\item[] Matthieu Sozeau for the Coq development team
\end{DUlineblock}


\paragraph{Changes in 8.14.0}
\label{\detokenize{changes:changes-in-8-14-0}}
\begin{sphinxShadowBox}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id955}}{\hyperref[\detokenize{changes:id1}]{\sphinxcrossref{Kernel}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id956}}{\hyperref[\detokenize{changes:id8}]{\sphinxcrossref{Specification language, type inference}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id957}}{\hyperref[\detokenize{changes:id19}]{\sphinxcrossref{Notations}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id958}}{\hyperref[\detokenize{changes:id36}]{\sphinxcrossref{Tactics}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id959}}{\hyperref[\detokenize{changes:id73}]{\sphinxcrossref{Tactic language}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id960}}{\hyperref[\detokenize{changes:id92}]{\sphinxcrossref{SSReflect}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id961}}{\hyperref[\detokenize{changes:id95}]{\sphinxcrossref{Commands and options}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id962}}{\hyperref[\detokenize{changes:id118}]{\sphinxcrossref{Command\sphinxhyphen{}line tools}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id963}}{\hyperref[\detokenize{changes:native-compilation}]{\sphinxcrossref{Native Compilation}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id964}}{\hyperref[\detokenize{changes:id133}]{\sphinxcrossref{CoqIDE}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id965}}{\hyperref[\detokenize{changes:id137}]{\sphinxcrossref{Standard library}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id966}}{\hyperref[\detokenize{changes:id163}]{\sphinxcrossref{Infrastructure and dependencies}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id967}}{\hyperref[\detokenize{changes:id169}]{\sphinxcrossref{Miscellaneous}}}

\end{itemize}
\end{sphinxShadowBox}


\subparagraph{Kernel}
\label{\detokenize{changes:id1}}\begin{quote}
\phantomsection\label{\detokenize{changes:caserepresentation}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The term representation of pattern\sphinxhyphen{}matchings now uses a compact form that
provides a few static guarantees such as eta\sphinxhyphen{}expansion of branches and return
clauses and is usually more efficient. The most visible user change is that for
the time being, the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} tactic and its variants generate dummy
cuts (β redexes) in the branches of the generated proof.
This can also generate very uncommon backwards incompatibilities, such as a
change of occurrence numbering for subterms, or breakage of unification in
complex situations involving pattern\sphinxhyphen{}matchings whose underlying inductive type
declares let\sphinxhyphen{}bindings in parameters, arity or constructor types. For ML plugin
developers, an in\sphinxhyphen{}depth description of the new representation, as well as
porting tips, can be found in dev/doc/case\sphinxhyphen{}repr.md
(\sphinxhref{https://github.com/coq/coq/pull/13563}{\#13563}%
\begin{footnote}[74]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13563}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/3166}{\#3166}%
\begin{footnote}[75]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/3166}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Linking of native\sphinxhyphen{}code libraries used by {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} is now delayed
until an actual call to the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} machinery is
performed. This should make Coq more responsive on some systems
(\sphinxhref{https://github.com/coq/coq/pull/13853}{\#13853}%
\begin{footnote}[76]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13853}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/13849}{\#13849}%
\begin{footnote}[77]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13849}
%
\end{footnote}, by Guillaume Melquiond).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} The ability to change typing flags inside
sections to prevent exploiting a weakness in {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Assumptions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print
Assumptions}}}}} (\sphinxhref{https://github.com/coq/coq/pull/14395}{\#14395}%
\begin{footnote}[78]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14395}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14317}{\#14317}%
\begin{footnote}[79]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14317}
%
\end{footnote}, by Gaëtan
Gilbert).

\end{itemize}


\subparagraph{Specification language, type inference}
\label{\detokenize{changes:id8}}\begin{quote}
\phantomsection\label{\detokenize{changes:tccanon}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The hints mode \sphinxcode{\sphinxupquote{!}} matches a term iff the applicative head is not an existential variable.
It now also matches projections applied to any term or a \sphinxcode{\sphinxupquote{match}} on any term.
(\sphinxhref{https://github.com/coq/coq/pull/14392}{\#14392}%
\begin{footnote}[80]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14392}
%
\end{footnote},
by Matthieu Sozeau).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
The little used \sphinxcode{\sphinxupquote{:>}} type cast, which was only interpreted in Program\sphinxhyphen{}mode
(\sphinxhref{https://github.com/coq/coq/pull/13911}{\#13911}%
\begin{footnote}[81]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13911}
%
\end{footnote},
by Jim Fehrle and Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Enable canonical \sphinxcode{\sphinxupquote{fun \_ => \_}} projections,
see {\hyperref[\detokenize{language/extensions/canonical:canonicalstructures}]{\sphinxcrossref{\DUrole{std,std-ref}{Canonical Structures}}}} for details.
(\sphinxhref{https://github.com/coq/coq/pull/14041}{\#14041}%
\begin{footnote}[82]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14041}
%
\end{footnote},
by Jan\sphinxhyphen{}Oliver Kaiser and Pierre Roux,
reviewed by Cyril Cohen and Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{language/extensions/canonical:coq:cmd.Canonical-Structure}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Canonical Structure}}}}} declarations now accept dependent function types
\sphinxcode{\sphinxupquote{forall \_, \_}} as keys.
(\sphinxhref{https://github.com/coq/coq/pull/14386}{\#14386}%
\begin{footnote}[83]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14386}
%
\end{footnote},
by Jan\sphinxhyphen{}Oliver Kaiser and Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Ability to declare primitive projections as class, for dependent typeclass resolutions
(\sphinxhref{https://github.com/coq/coq/pull/9711}{\#9711}%
\begin{footnote}[84]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9711}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12975}{\#12975}%
\begin{footnote}[85]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12975}
%
\end{footnote},
by Matthieu Sozeau).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Multiple printing of same warning about unused variables catching several cases
(\sphinxhref{https://github.com/coq/coq/pull/14261}{\#14261}%
\begin{footnote}[86]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14261}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14207}{\#14207}%
\begin{footnote}[87]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14207}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Constants \sphinxcode{\sphinxupquote{\DUrole{name}{id}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{not}}} were unduly set opaque in some parts
of the unification algorithm
(\sphinxhref{https://github.com/coq/coq/pull/14371}{\#14371}%
\begin{footnote}[88]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14371}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14374}{\#14374}%
\begin{footnote}[89]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14374}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Notations}
\label{\detokenize{changes:id19}}\begin{quote}
\phantomsection\label{\detokenize{changes:id20}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Flag {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:flag.Printing-Notations}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Notations}}}}} no longer controls
whether strings and numbers are printed raw
(\sphinxhref{https://github.com/coq/coq/pull/13840}{\#13840}%
\begin{footnote}[90]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13840}
%
\end{footnote},
by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The error \sphinxcode{\sphinxupquote{Argument X was previously inferred to be in scope
XXX\_scope but is here used in YYY\_scope.}} is now the warning
\sphinxcode{\sphinxupquote{{[}inconsistent\sphinxhyphen{}scopes,syntax{]}}} and can be silenced by
specifying the scope of the argument
(\sphinxhref{https://github.com/coq/coq/pull/13965}{\#13965}%
\begin{footnote}[91]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13965}
%
\end{footnote},
by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Decimal\sphinxhyphen{}only number notations which were deprecated in 8.12.
(\sphinxhref{https://github.com/coq/coq/pull/13842}{\#13842}%
\begin{footnote}[92]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13842}
%
\end{footnote}, by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} and {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}} now support
parsing and printing of primitive floats, primitive arrays
and type constants of primitive types.
(\sphinxhref{https://github.com/coq/coq/pull/13519}{\#13519}%
\begin{footnote}[93]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13519}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13484}{\#13484}%
\begin{footnote}[94]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13484}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/13517}{\#13517}%
\begin{footnote}[95]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13517}
%
\end{footnote},
by Fabian Kunze, with help of Jason Gross)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Flag {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:flag.Printing-Raw-Literals}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Raw Literals}}}}} to control whether
strings and numbers are printed raw.
(\sphinxhref{https://github.com/coq/coq/pull/13840}{\#13840}%
\begin{footnote}[96]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13840}
%
\end{footnote},
by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Let the user specify a scope for abbreviation arguments, e.g.
\sphinxcode{\sphinxupquote{Notation abbr X := t (X in scope my\_scope)}}.
(\sphinxhref{https://github.com/coq/coq/pull/13965}{\#13965}%
\begin{footnote}[97]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13965}
%
\end{footnote},
by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Look\sphinxhyphen{}ahead of tokens is changed from sequential to tree\sphinxhyphen{}based,
allowing more automatic rule factorizations in notations
(\sphinxhref{https://github.com/coq/coq/pull/14070}{\#14070}%
\begin{footnote}[98]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14070}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Non\sphinxhyphen{}local custom entries survive module closing and are
declared when a file is Required
(\sphinxhref{https://github.com/coq/coq/pull/14183}{\#14183}%
\begin{footnote}[99]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14183}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13654}{\#13654}%
\begin{footnote}[100]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13654}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
\sphinxcode{\sphinxupquote{\DUrole{name}{ident}}} modifier in custom entry notations gave fatal errors at printing time
(\sphinxhref{https://github.com/coq/coq/pull/14257}{\#14257}%
\begin{footnote}[101]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14257}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14211}{\#14211}%
\begin{footnote}[102]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14211}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Anomaly when overriding a notation with different applicability in
\sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} patterns
(\sphinxhref{https://github.com/coq/coq/pull/14377}{\#14377}%
\begin{footnote}[103]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14377}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13966}{\#13966}%
\begin{footnote}[104]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13966}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Tactics}
\label{\detokenize{changes:id36}}\begin{quote}
\phantomsection\label{\detokenize{changes:id37}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
More systematic checks that occurrences of an \sphinxcode{\sphinxupquote{\DUrole{notation}{at}}} clause are
valid in tactics such as {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/13568}{\#13568}%
\begin{footnote}[105]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13568}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13566}{\#13566}%
\begin{footnote}[106]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13566}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fail}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.gfail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{gfail}}}}}, which formerly accepted negative
values as a parameter, now give syntax errors for negative
values (\sphinxhref{https://github.com/coq/coq/pull/13469}{\#13469}%
\begin{footnote}[107]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13469}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Deprecated flag \sphinxcode{\sphinxupquote{Bracketing Last Introduction Pattern}} affecting the
behavior of trailing disjunctive introduction patterns is
definitively removed
(\sphinxhref{https://github.com/coq/coq/pull/13509}{\#13509}%
\begin{footnote}[108]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13509}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
The \sphinxcode{\sphinxupquote{omega}} tactic (deprecated in 8.12) and four \sphinxcode{\sphinxupquote{* Omega *}} flags.
Use \sphinxcode{\sphinxupquote{lia}} instead.
(\sphinxhref{https://github.com/coq/coq/pull/13741}{\#13741}%
\begin{footnote}[109]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13741}
%
\end{footnote},
by Jim Fehrle, who addressed the final details, building on much work by
Frédéric Besson, who greatly improved {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}}, Maxime Dénès,
Vincent Laporte and with the help of many package maintainers, among others).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
convert\_concl\_no\_check.  Use {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change\_no\_check}}}}} instead
(\sphinxhref{https://github.com/coq/coq/pull/13761}{\#13761}%
\begin{footnote}[110]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13761}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
double induction tactic.  Replace \sphinxcode{\sphinxupquote{\DUrole{notation}{double induction {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
with \sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; induction {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} (or
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} ; destruct {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} depending on the exact needs).
Replace \sphinxcode{\sphinxupquote{\DUrole{notation}{double induction {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural$_{\text{1}}$}}}} {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural$_{\text{2}}$}}}}}}} with
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/core/basic:grammar-token-natural}]{\sphinxcrossref{\DUrole{hole}{natural$_{\text{1}}$}}}}; induction natural$_{\text{3}}$}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{natural$_{\text{3}}$}}} is the result
of \sphinxcode{\sphinxupquote{\DUrole{notation}{natural$_{\text{2}}$ \sphinxhyphen{} natural$_{\text{1}}$}}}
(\sphinxhref{https://github.com/coq/coq/pull/13762}{\#13762}%
\begin{footnote}[111]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13762}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
In {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change\_no\_check}}}}}, the
\sphinxcode{\sphinxupquote{at ... with ...}} form is deprecated.  Use
\sphinxcode{\sphinxupquote{with ... at ...}} instead.  For \sphinxcode{\sphinxupquote{at ... with ... in H |\sphinxhyphen{}}},
use \sphinxcode{\sphinxupquote{with ... in H at ... |\sphinxhyphen{}}}.
(\sphinxhref{https://github.com/coq/coq/pull/13696}{\#13696}%
\begin{footnote}[112]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13696}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
The micromega option {\hyperref[\detokenize{addendum/micromega:coq:flag.Simplex}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Simplex}}}}}, which is currently set by default
(\sphinxhref{https://github.com/coq/coq/pull/13781}{\#13781}%
\begin{footnote}[113]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13781}
%
\end{footnote}, by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
the undocumented \sphinxcode{\sphinxupquote{new auto}} tactic
(\sphinxhref{https://github.com/coq/coq/pull/14528}{\#14528}%
\begin{footnote}[114]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14528}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} supports the boolean operator \sphinxcode{\sphinxupquote{Bool.implb}} (\sphinxhref{https://github.com/coq/coq/pull/13715}{\#13715}%
\begin{footnote}[115]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13715}
%
\end{footnote}, by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{zify}} (\sphinxcode{\sphinxupquote{lia}}/\sphinxcode{\sphinxupquote{nia}}) support for \sphinxcode{\sphinxupquote{\DUrole{name}{div}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{mod}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{pow}}}
for \sphinxcode{\sphinxupquote{\DUrole{name}{Nat}}} (via \sphinxcode{\sphinxupquote{ZifyNat}} module) and \sphinxcode{\sphinxupquote{\DUrole{name}{N}}} (via \sphinxcode{\sphinxupquote{ZifyN}} module).
The signature of \sphinxcode{\sphinxupquote{\DUrole{name}{Z\_div\_mod\_eq\_full}}} has no assumptions.
(\sphinxhref{https://github.com/coq/coq/pull/14037}{\#14037}%
\begin{footnote}[116]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14037}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11447}{\#11447}%
\begin{footnote}[117]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11447}
%
\end{footnote},
by Andrej Dudenhefner, Jason Gross, and Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Ltac2 now has a \sphinxcode{\sphinxupquote{unify}} tactic
(\sphinxhref{https://github.com/coq/coq/pull/14089}{\#14089}%
\begin{footnote}[118]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14089}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14083}{\#14083}%
\begin{footnote}[119]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14083}
%
\end{footnote},
by Samuel Gruetter).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_sigma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion\_sigma}}}}} can now be applied to a specified hypothesis
and additionally supports intropatterns, so it can be used much like
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}}.  Additionally,
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_sigma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion\_sigma}}}}} now supports the types \sphinxcode{\sphinxupquote{\DUrole{notation}{ex}}} (\sphinxcode{\sphinxupquote{\DUrole{notation}{exists x
: A, P x}}}) and \sphinxcode{\sphinxupquote{\DUrole{notation}{ex2}}} (\sphinxcode{\sphinxupquote{\DUrole{notation}{exists2 x : A, P x \& Q x}}}) in cases
where the first argument \sphinxcode{\sphinxupquote{\DUrole{notation}{A}}} is a \sphinxcode{\sphinxupquote{\DUrole{notation}{Prop}}} (\sphinxhref{https://github.com/coq/coq/pull/14174}{\#14174}%
\begin{footnote}[120]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14174}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{zify}} (\sphinxcode{\sphinxupquote{lia}}/\sphinxcode{\sphinxupquote{nia}}) support for \sphinxcode{\sphinxupquote{Sint63}}.
(\sphinxhref{https://github.com/coq/coq/pull/14408}{\#14408}%
\begin{footnote}[121]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14408}
%
\end{footnote},
by Ana Borges, with help from Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Possible collision between a user\sphinxhyphen{}level name and an internal name when
using the \sphinxcode{\sphinxupquote{\DUrole{notation}{\%}}} introduction pattern
(\sphinxhref{https://github.com/coq/coq/pull/13512}{\#13512}%
\begin{footnote}[122]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13512}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13413}{\#13413}%
\begin{footnote}[123]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13413}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}} now reduce primitive functions
on primitive integers, floats and arrays
(\sphinxhref{https://github.com/coq/coq/pull/13699}{\#13699}%
\begin{footnote}[124]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13699}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13579}{\#13579}%
\begin{footnote}[125]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13579}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Setoid rewriting now remembers the (invisible) binder names of non\sphinxhyphen{}dependent product types. SSReflect's rewrite tactic expects these names to be retained when using \sphinxcode{\sphinxupquote{rewrite foo in H}}.
This also fixes SSR \sphinxcode{\sphinxupquote{rewrite foo in H *}} erroneously reverting \sphinxcode{\sphinxupquote{H}}.
(\sphinxhref{https://github.com/coq/coq/pull/13882}{\#13882}%
\begin{footnote}[126]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13882}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12011}{\#12011}%
\begin{footnote}[127]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12011}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Properly expand projection parameters in hint discrimination
nets. (\sphinxhref{https://github.com/coq/coq/pull/14033}{\#14033}%
\begin{footnote}[128]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14033}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9000}{\#9000}%
\begin{footnote}[129]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9000}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/issues/14009}{\#14009}%
\begin{footnote}[130]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14009}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
anomalies caused by empty strings in Ltac notations are now errors
(\sphinxhref{https://github.com/coq/coq/pull/14378}{\#14378}%
\begin{footnote}[131]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14378}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14124}{\#14124}%
\begin{footnote}[132]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14124}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Print a message instead of a Diff\_Failure anomaly when
old and new goals can't be matched; show the goal without
diff highlights
(\sphinxhref{https://github.com/coq/coq/pull/14457}{\#14457}%
\begin{footnote}[133]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14457}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14425}{\#14425}%
\begin{footnote}[134]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14425}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Anomaly of {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} on terms with dependent variables unused in goal
(\sphinxhref{https://github.com/coq/coq/pull/15099}{\#15099}%
\begin{footnote}[135]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/15099}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11504}{\#11504}%
\begin{footnote}[136]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11504}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/14090}{\#14090}%
\begin{footnote}[137]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14090}
%
\end{footnote},
by Lasse Blaauwbroek and Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Correct convertibility of multiple terms selected by patterns in
tactics such as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{set}}}}} when these terms have subterms in
\sphinxcode{\sphinxupquote{SProp}}
(\sphinxhref{https://github.com/coq/coq/pull/14610}{\#14610}%
\begin{footnote}[138]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14610}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14609}{\#14609}%
\begin{footnote}[139]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14609}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Tactic language}
\label{\detokenize{changes:id73}}\begin{quote}
\phantomsection\label{\detokenize{changes:ltac2}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Renamed Ltac2 \sphinxcode{\sphinxupquote{Bool.eq}} into \sphinxcode{\sphinxupquote{Bool.equal}} for uniformity.
The old function is now a deprecated alias
(\sphinxhref{https://github.com/coq/coq/pull/14128}{\#14128}%
\begin{footnote}[140]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14128}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A \sphinxcode{\sphinxupquote{printf}} macro to Ltac2. It can be made accessible by
importing the \sphinxcode{\sphinxupquote{Ltac2.Printf}} module. See the documentation
there for more information
(\sphinxhref{https://github.com/coq/coq/pull/13236}{\#13236}%
\begin{footnote}[141]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13236}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10108}{\#10108}%
\begin{footnote}[142]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10108}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A function \sphinxcode{\sphinxupquote{Ltac1.lambda}} allowing to embed Ltac2 functions
into Ltac1 runtime values
(\sphinxhref{https://github.com/coq/coq/pull/13442}{\#13442}%
\begin{footnote}[143]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13442}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12871}{\#12871}%
\begin{footnote}[144]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12871}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Ltac2 commands defining terms now accept the {\hyperref[\detokenize{using/libraries/writing:coq:attr.deprecated}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{deprecated}}}}}
attribute
(\sphinxhref{https://github.com/coq/coq/pull/13774}{\#13774}%
\begin{footnote}[145]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13774}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12317}{\#12317}%
\begin{footnote}[146]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12317}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Allow the presence of type casts for function return values, let bindings and
global definitions in Ltac2
(\sphinxhref{https://github.com/coq/coq/pull/13914}{\#13914}%
\begin{footnote}[147]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13914}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The Ltac2 API \sphinxcode{\sphinxupquote{Ltac2.Ind}} for manipulating inductive types
(\sphinxhref{https://github.com/coq/coq/pull/13920}{\#13920}%
\begin{footnote}[148]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13920}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10095}{\#10095}%
\begin{footnote}[149]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10095}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Allow scope delimiters in Ltac2 \sphinxcode{\sphinxupquote{open\_constr:(...)}} quotation
(\sphinxhref{https://github.com/coq/coq/pull/13939}{\#13939}%
\begin{footnote}[150]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13939}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12806}{\#12806}%
\begin{footnote}[151]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12806}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A FFI to convert between Ltac1 and Ltac2 identifiers
(\sphinxhref{https://github.com/coq/coq/pull/13997}{\#13997}%
\begin{footnote}[152]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13997}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13996}{\#13996}%
\begin{footnote}[153]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13996}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lazy evaluating boolean operators \sphinxcode{\sphinxupquote{lazy\_and}}, \sphinxcode{\sphinxupquote{lazy\_or}}, \sphinxcode{\sphinxupquote{lazy\_impl}} and infix notations \sphinxcode{\sphinxupquote{\&\&}} and \sphinxcode{\sphinxupquote{||}} to the Ltac2 \sphinxcode{\sphinxupquote{Bool.v}} library l.
(\sphinxhref{https://github.com/coq/coq/pull/14081}{\#14081}%
\begin{footnote}[154]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14081}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13964}{\#13964}%
\begin{footnote}[155]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13964}
%
\end{footnote},
by Michael Soegtrop).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Ltac2 notations now correctly take into account their assigned level
(\sphinxhref{https://github.com/coq/coq/pull/14094}{\#14094}%
\begin{footnote}[156]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14094}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11866}{\#11866}%
\begin{footnote}[157]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11866}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}


\subparagraph{SSReflect}
\label{\detokenize{changes:id92}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A test that the notations \sphinxcode{\sphinxupquote{\{in \_, \_\}}} and \sphinxcode{\sphinxupquote{\{pred \_\}}} from \sphinxcode{\sphinxupquote{ssrbool.v}} are displayed correctly.
(\sphinxhref{https://github.com/coq/coq/pull/13473}{\#13473}%
\begin{footnote}[158]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13473}
%
\end{footnote},
by Cyril Cohen).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas about interaction between \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{in \_, \_\}}}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{on \_, \_\}}}}}, and \sphinxcode{\sphinxupquote{\DUrole{notation}{sig}}}
have been backported from Mathematical Components 1.12.0
(\sphinxhref{https://github.com/coq/coq/pull/13490}{\#13490}%
\begin{footnote}[159]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13490}
%
\end{footnote},
by Kazuhiko Sakaguchi).

\end{itemize}


\subparagraph{Commands and options}
\label{\detokenize{changes:id95}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Rewrite}}}}} now supports locality attributes (including {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}}) like other {\hyperref[\detokenize{proofs/automatic-tactics/auto:creating-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Hint}}}} commands
(\sphinxhref{https://github.com/coq/coq/pull/13725}{\#13725}%
\begin{footnote}[160]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13725}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13724}{\#13724}%
\begin{footnote}[161]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13724}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
In {\hyperref[\detokenize{language/core/records:coq:cmd.Record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}}, alpha\sphinxhyphen{}rename the variable associated with the record to avoid
alpha\sphinxhyphen{}renaming parameters of projections
(\sphinxhref{https://github.com/coq/coq/pull/13852}{\#13852}%
\begin{footnote}[162]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13852}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13727}{\#13727}%
\begin{footnote}[163]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13727}
%
\end{footnote},
by Li\sphinxhyphen{}yao Xia).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Improve the {\hyperref[\detokenize{addendum/implicit-coercions:coq:cmd.Coercion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Coercion}}}}} command to reduce the number of ambiguous paths to
report. A pair of multiple inheritance paths that can be reduced to smaller
adjoining pairs will not be reported as ambiguous paths anymore.
(\sphinxhref{https://github.com/coq/coq/pull/13909}{\#13909}%
\begin{footnote}[164]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13909}
%
\end{footnote},
by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The printing order of {\hyperref[\detokenize{addendum/implicit-coercions:coq:cmd.Print-Classes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Classes}}}}} and {\hyperref[\detokenize{addendum/implicit-coercions:coq:cmd.Print-Graph}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Graph}}}}}, due to the
changes for the internal tables of coercion classes and coercion paths.
(\sphinxhref{https://github.com/coq/coq/pull/13912}{\#13912}%
\begin{footnote}[165]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13912}
%
\end{footnote},
by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
The Hide Obligations flag, deprecated in 8.12
(\sphinxhref{https://github.com/coq/coq/pull/13758}{\#13758}%
\begin{footnote}[166]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13758}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
SearchHead command.  Use the \sphinxcode{\sphinxupquote{headconcl:}} clause of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} instead
(\sphinxhref{https://github.com/coq/coq/pull/13763}{\#13763}%
\begin{footnote}[167]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13763}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
\sphinxcode{\sphinxupquote{Show Zify Spec}}, \sphinxcode{\sphinxupquote{Add InjTyp}} and 11 similar \sphinxcode{\sphinxupquote{Add *}} commands.
For \sphinxcode{\sphinxupquote{Show Zify Spec}}, use \sphinxcode{\sphinxupquote{Show Zify UnOpSpec}} or \sphinxcode{\sphinxupquote{Show Zify BinOpSpec}} instead.
For \sphinxcode{\sphinxupquote{Add *}}, \sphinxcode{\sphinxupquote{Use Add Zify *}} intead of \sphinxcode{\sphinxupquote{Add *}}
(\sphinxhref{https://github.com/coq/coq/pull/13764}{\#13764}%
\begin{footnote}[168]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13764}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
Like hints, typeclass instances added outside of sections
without an explicit locality now generate a deprecation warning. See
{\hyperref[\detokenize{proofs/automatic-tactics/auto:creating-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Hint}}}}
(\sphinxhref{https://github.com/coq/coq/pull/14208}{\#14208}%
\begin{footnote}[169]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14208}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13562}{\#13562}%
\begin{footnote}[170]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13562}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:flag.Regular-Subst-Tactic}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Regular Subst Tactic}}}}} flag
(\sphinxhref{https://github.com/coq/coq/pull/14336}{\#14336}%
\begin{footnote}[171]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14336}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Debug}}}}} to control debug messages, functioning similarly to the warning system
(\sphinxhref{https://github.com/coq/coq/pull/13202}{\#13202}%
\begin{footnote}[172]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13202}
%
\end{footnote},
by Maxime Dénès and Gaëtan Gilbert).
The following flags have been converted (such that \sphinxcode{\sphinxupquote{Set Flag}} becomes \sphinxcode{\sphinxupquote{Set Debug "flag"}}):
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Debug Unification}} to \sphinxcode{\sphinxupquote{unification}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Debug HO Unification}} to \sphinxcode{\sphinxupquote{ho\sphinxhyphen{}unification}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Debug Tactic Unification}} to \sphinxcode{\sphinxupquote{tactic\sphinxhyphen{}unification}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Congruence Verbose}} to \sphinxcode{\sphinxupquote{congruence}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Debug Cbv}} to \sphinxcode{\sphinxupquote{cbv}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Debug RAKAM}} to \sphinxcode{\sphinxupquote{RAKAM}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Debug Ssreflect}} to \sphinxcode{\sphinxupquote{ssreflect}}

\end{itemize}

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The Ltac2 grammar can now be printed using the
Print Grammar ltac2 command
(\sphinxhref{https://github.com/coq/coq/pull/14093}{\#14093}%
\begin{footnote}[173]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14093}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14092}{\#14092}%
\begin{footnote}[174]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14092}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{addendum/type-classes:coq:cmd.Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} now accepts the {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}} locality
attribute
(\sphinxhref{https://github.com/coq/coq/pull/14148}{\#14148}%
\begin{footnote}[175]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14148}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
extraction failure of a parameterized type in \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}} exported in
an module interface as an assumption in \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}
(\sphinxhref{https://github.com/coq/coq/pull/14102}{\#14102}%
\begin{footnote}[176]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14102}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14100}{\#14100}%
\begin{footnote}[177]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14100}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Print Assumptions now treats delayed opaque proofs generated
by vos compilation as if they were axioms
(\sphinxhref{https://github.com/coq/coq/pull/14382}{\#14382}%
\begin{footnote}[178]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14382}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13589}{\#13589}%
\begin{footnote}[179]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13589}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Incorrect de Bruijn index handling in vernac class declaration,
preventing users from marking existing instances of existing classes
which are primitive projections
(\sphinxhref{https://github.com/coq/coq/pull/14664}{\#14664}%
\begin{footnote}[180]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14664}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14652}{\#14652}%
\begin{footnote}[181]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14652}
%
\end{footnote},
by Ali Caglayan and Hugo Herbelin).

\end{itemize}


\subparagraph{Command\sphinxhyphen{}line tools}
\label{\detokenize{changes:id118}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
\sphinxcode{\sphinxupquote{coqc}} now enforces that at most a single \sphinxcode{\sphinxupquote{.v}} file can be passed in
the command line. Support for multiple \sphinxcode{\sphinxupquote{.v}} files in the form of
\sphinxcode{\sphinxupquote{coqc f1.v f2.v}} didn't properly work in 8.13, tho it was accepted.
(\sphinxhref{https://github.com/coq/coq/pull/13876}{\#13876}%
\begin{footnote}[182]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13876}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
\sphinxcode{\sphinxupquote{coqdep}} now reports an error if files specified on the
command line don't exist or if it encounters unreadable files.
Unknown options now generate a warning. Previously these
conditions were ignored.
(\sphinxhref{https://github.com/coq/coq/pull/14024}{\#14024}%
\begin{footnote}[183]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14024}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14023}{\#14023}%
\begin{footnote}[184]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14023}
%
\end{footnote},
by Hendrik Tews).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Makefiles produced by \sphinxcode{\sphinxupquote{coq\_makefile}} now use \sphinxcode{\sphinxupquote{.DELETE\_ON\_ERROR}}
(\sphinxhref{https://github.com/coq/coq/pull/14238}{\#14238}%
\begin{footnote}[185]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14238}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Previously deprecated command line options
\sphinxcode{\sphinxupquote{\sphinxhyphen{}sprop\sphinxhyphen{}cumulative}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}input\sphinxhyphen{}state}} and its alias \sphinxcode{\sphinxupquote{\sphinxhyphen{}is}}
(\sphinxhref{https://github.com/coq/coq/pull/13822}{\#13822}%
\begin{footnote}[186]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13822}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{coq\_makefile}}\sphinxhyphen{}made \sphinxcode{\sphinxupquote{Makefile}}s now support inclusion of a
\sphinxcode{\sphinxupquote{.local\sphinxhyphen{}late}} file at the end, allowing the user to access
more variables (\sphinxhref{https://github.com/coq/coq/pull/12411}{\#12411}%
\begin{footnote}[187]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12411}
%
\end{footnote}, fixes
\sphinxhref{https://github.com/coq/coq/issues/10912}{\#10912}%
\begin{footnote}[188]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10912}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Failure of extraction in the presence of inductive types with local
definitions in parameters
(\sphinxhref{https://github.com/coq/coq/pull/13624}{\#13624}%
\begin{footnote}[189]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13624}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13581}{\#13581}%
\begin{footnote}[190]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13581}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
File name was missing in coqdoc error position reporting
(\sphinxhref{https://github.com/coq/coq/pull/14285}{\#14285}%
\begin{footnote}[191]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14285}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14283}{\#14283}%
\begin{footnote}[192]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14283}
%
\end{footnote},
by Arthur Charguéraud and Hugo Herbelin).

\end{itemize}


\subparagraph{Native Compilation}
\label{\detokenize{changes:native-compilation}}\begin{quote}
\phantomsection\label{\detokenize{changes:coqnative}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
\sphinxcode{\sphinxupquote{coq\_makefile}} now uses the \sphinxcode{\sphinxupquote{coqnative}} binary to generate
native compilation files. Project files also understand directly the
\sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler}} flag without having to wrap it with \sphinxcode{\sphinxupquote{\sphinxhyphen{}arg}}
(\sphinxhref{https://github.com/coq/coq/pull/14265}{\#14265}%
\begin{footnote}[193]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14265}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
the \sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler}} option for coqc. It is now recommended
to use the {\hyperref[\detokenize{practical-tools/utilities:coqnative}]{\sphinxcrossref{\DUrole{std,std-ref}{Split compilation of native computation files}}}} binary instead to generate native
compilation files ahead of time
(\sphinxhref{https://github.com/coq/coq/pull/14309}{\#14309}%
\begin{footnote}[194]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14309}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A standalone \sphinxcode{\sphinxupquote{coqnative}} binary that performs native compilation
out of \sphinxcode{\sphinxupquote{vo}} files, allowing to split library compilation from
native compilation. See {\hyperref[\detokenize{practical-tools/utilities:coqnative}]{\sphinxcrossref{\DUrole{std,std-ref}{Split compilation of native computation files}}}}. The hybrid build
system was adapted to perform a split compilation on the stdlib
(\sphinxhref{https://github.com/coq/coq/pull/13287}{\#13287}%
\begin{footnote}[195]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13287}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}


\subparagraph{CoqIDE}
\label{\detokenize{changes:id133}}\begin{quote}
\phantomsection\label{\detokenize{changes:id134}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Ltac debugger support in CoqIDE (see {\hyperref[\detokenize{proof-engine/ltac:coq:flag.Ltac-Debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac Debug}}}}}).
Debugger output and prompts appear in the Messages panel
(\sphinxhref{https://github.com/coq/coq/pull/13783}{\#13783}%
\begin{footnote}[196]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13783}
%
\end{footnote},
by Jim Fehrle and Emilio J. Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Shift\sphinxhyphen{}return in the Find dialog now searches backwards (\sphinxhref{https://github.com/coq/coq/pull/13810}{\#13810}%
\begin{footnote}[197]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13810}
%
\end{footnote},
by slrnsc).

\end{itemize}


\subparagraph{Standard library}
\label{\detokenize{changes:id137}}\begin{quote}
\phantomsection\label{\detokenize{changes:stdlib}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Minor Changes to \sphinxcode{\sphinxupquote{Rpower}}:
Generalizes \sphinxcode{\sphinxupquote{exp\_ineq1}} to hold for all non\sphinxhyphen{}zero numbers.
Adds \sphinxcode{\sphinxupquote{exp\_ineq1\_le}}, which holds for all reals (but is a \sphinxcode{\sphinxupquote{<=}} instead of a \sphinxcode{\sphinxupquote{<}}).
(\sphinxhref{https://github.com/coq/coq/pull/13582}{\#13582}%
\begin{footnote}[198]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13582}
%
\end{footnote},
by Avi Shinnar and Barry Trager, with help from Laurent Théry).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
set \sphinxcode{\sphinxupquote{\DUrole{name}{n} \DUrole{name}{mod} \DUrole{literal,number,integer}{0} \DUrole{operator}{=} \DUrole{name}{n}}} uniformly for \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{N}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{int63}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{sint63}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{int31}}}
such that \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{=} \DUrole{operator}{(}\DUrole{name}{m} \DUrole{operator}{/} \DUrole{name}{n}\DUrole{operator}{)} \DUrole{operator}{*} \DUrole{name}{n} \DUrole{operator}{+} \DUrole{operator}{(}\DUrole{name}{m} \DUrole{name}{mod} \DUrole{name}{n}\DUrole{operator}{)}}} holds (also for \sphinxcode{\sphinxupquote{\DUrole{name}{n} \DUrole{operator}{=} \DUrole{literal,number,integer}{0}}})

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
code that relies on \sphinxcode{\sphinxupquote{\DUrole{name}{n} \DUrole{name}{mod} \DUrole{literal,number,integer}{0} \DUrole{operator}{=} \DUrole{literal,number,integer}{0}}} will break;
for compatibility with both \sphinxcode{\sphinxupquote{\DUrole{name}{n} \DUrole{name}{mod} \DUrole{literal,number,integer}{0} \DUrole{operator}{=} \DUrole{name}{n}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{n} \DUrole{name}{mod} \DUrole{literal,number,integer}{0} \DUrole{operator}{=} \DUrole{literal,number,integer}{0}}} you can use
\sphinxcode{\sphinxupquote{\DUrole{name}{n} \DUrole{name}{mod} \DUrole{literal,number,integer}{0} \DUrole{operator}{=} \DUrole{name}{ltac}\DUrole{operator}{:(}\DUrole{keyword}{match} \DUrole{name}{eval} \DUrole{keyword}{hnf} \DUrole{keyword}{in} \DUrole{operator}{(}\DUrole{literal,number,integer}{1} \DUrole{name}{mod} \DUrole{literal,number,integer}{0}\DUrole{operator}{)} \DUrole{keyword}{with} \DUrole{operator}{|}\DUrole{literal,number,integer}{0} \DUrole{operator}{=>} \DUrole{keyword,pseudo}{exact} \DUrole{literal,number,integer}{0} \DUrole{operator}{|\_} \DUrole{operator}{=>} \DUrole{keyword,pseudo}{exact} \DUrole{name}{n} \DUrole{keyword}{end}\DUrole{operator}{)}}}
\end{sphinxadmonition}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/14086}{\#14086}%
\begin{footnote}[199]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14086}
%
\end{footnote},
by Andrej Dudenhefner with help of Guillaume Melquiond, Jason Gross, and Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The standard library now contains a more complete theory of equality
on types of the form \sphinxcode{\sphinxupquote{\DUrole{keyword}{exists} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{A}\DUrole{operator}{,} \DUrole{name}{P} \DUrole{name}{x}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword}{exists2} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{A}\DUrole{operator}{,} \DUrole{name}{P}
\DUrole{name}{x} \DUrole{operator}{\&} \DUrole{name}{Q} \DUrole{name}{x}}} when we have \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{:} \DUrole{keyword,type}{Prop}}}.  To bring this theory more in
line with the existing theory about sigma types,
\sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex\_uncurried}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex2\_uncurried}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex2}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex\_hprop}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex2\_hprop}}} have been renamed
into \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex\_intro\_uncurried}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex\_intro2\_uncurried}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex\_intro}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex\_intro2}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex\_intro\_hprop}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{eq\_ex\_intro2\_hprop}}} respectively and the implicit status of
these lemmas has changed slightly (\sphinxhref{https://github.com/coq/coq/pull/14174}{\#14174}%
\begin{footnote}[200]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14174}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed}
Moved 39 lemmas and notations about the rationals \sphinxcode{\sphinxupquote{Q}} from the constructive reals private file \sphinxcode{\sphinxupquote{theories/Reals/Cauchy/QExtra.v}} to appropriate files in \sphinxcode{\sphinxupquote{theories/QArith}}.
The now public lemmas are mostly about compatibility of multiplication and power with relational operators and simple convenience lemmas e.g. for reduction of \sphinxcode{\sphinxupquote{Q}} values.
The following moved lemmas have been renamed:
\sphinxcode{\sphinxupquote{Q\_factorDenom}} to \sphinxcode{\sphinxupquote{Qmult\_frac\_l}},
\sphinxcode{\sphinxupquote{Q\_reduce\_fl}} to \sphinxcode{\sphinxupquote{Qreduce\_num\_l}},
\sphinxcode{\sphinxupquote{Qle\_neq}} to \sphinxcode{\sphinxupquote{Qlt\_leneq}},
\sphinxcode{\sphinxupquote{Qmult\_lt\_le\_compat\_nonneg}} to \sphinxcode{\sphinxupquote{Qmult\_le\_lt\_compat\_pos}},
\sphinxcode{\sphinxupquote{Qpower\_pos\_lt}} to \sphinxcode{\sphinxupquote{Qpower\_0\_lt}},
\sphinxcode{\sphinxupquote{Qpower\_lt\_1\_increasing}} to \sphinxcode{\sphinxupquote{Qpower\_1\_lt\_pos}},
\sphinxcode{\sphinxupquote{Qpower\_lt\_1\_increasing'}} to \sphinxcode{\sphinxupquote{Qpower\_1\_lt}},
\sphinxcode{\sphinxupquote{Qpower\_le\_1\_increasing}} to \sphinxcode{\sphinxupquote{Qpower\_1\_le\_pos}},
\sphinxcode{\sphinxupquote{Qpower\_le\_1\_increasing'}} to \sphinxcode{\sphinxupquote{Qpower\_1\_le}},
\sphinxcode{\sphinxupquote{Qzero\_eq}} to \sphinxcode{\sphinxupquote{Qreduce\_zero}},
\sphinxcode{\sphinxupquote{Qpower\_lt\_compat}} to \sphinxcode{\sphinxupquote{Qpower\_lt\_compat\_l}},
\sphinxcode{\sphinxupquote{Qpower\_le\_compat}} to \sphinxcode{\sphinxupquote{Qpower\_le\_compat\_l}},
\sphinxcode{\sphinxupquote{Qpower\_lt\_compat\_inv}} to \sphinxcode{\sphinxupquote{Qpower\_lt\_compat\_l\_inv}},
\sphinxcode{\sphinxupquote{Qpower\_le\_compat\_inv}} to \sphinxcode{\sphinxupquote{Qpower\_le\_compat\_l\_inv}},
\sphinxcode{\sphinxupquote{Qpower\_decomp'}} to \sphinxcode{\sphinxupquote{Qpower\_decomp\_pos}} and
\sphinxcode{\sphinxupquote{QarchimedeanExp2\_Pos}} to \sphinxcode{\sphinxupquote{Qarchimedean\_power2\_pos}}.
The following lemmas have been renamed and the sides of the equality swapped:
\sphinxcode{\sphinxupquote{Qinv\_swap\_pos}} to \sphinxcode{\sphinxupquote{Qinv\_pos}},
\sphinxcode{\sphinxupquote{Qinv\_swap\_neg}} to \sphinxcode{\sphinxupquote{Qinv\_neg}} and.
The following lemmas have been deleted:
\sphinxcode{\sphinxupquote{Q\_factorNum\_l}} and \sphinxcode{\sphinxupquote{Q\_factorNum}}.
The lemma \sphinxcode{\sphinxupquote{Qopp\_lt\_compat}} has been moved from \sphinxcode{\sphinxupquote{theories/QArith/Qround.v}} to \sphinxcode{\sphinxupquote{theories/QArith/QArith\_base.v}}.
About 10 additional lemmas have been added for similar cases as the moved lemmas.
Compatibility notations are not provided because QExtra is considered internal (excluded from the library documentation).
(\sphinxhref{https://github.com/coq/coq/pull/14293}{\#14293}%
\begin{footnote}[201]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14293}
%
\end{footnote},
by Michael Soegtrop).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Importing \sphinxcode{\sphinxupquote{ZArith}} no longer has the side\sphinxhyphen{}effect of closing \sphinxcode{\sphinxupquote{Z\_scope}}.
(\sphinxhref{https://github.com/coq/coq/pull/14343}{\#14343}%
\begin{footnote}[202]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14343}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13307}{\#13307}%
\begin{footnote}[203]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13307}
%
\end{footnote},
by Ralf Jung).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
\sphinxcode{\sphinxupquote{IF\_then\_else}} definition and corresponding \sphinxcode{\sphinxupquote{IF P then Q else R}} notation
(\sphinxhref{https://github.com/coq/coq/pull/13871}{\#13871}%
\begin{footnote}[204]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13871}
%
\end{footnote},
by Yishuai Li).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
from \sphinxcode{\sphinxupquote{List.v}} deprecated/unexpected dependencies \sphinxcode{\sphinxupquote{Setoid}}, \sphinxcode{\sphinxupquote{Le}}, \sphinxcode{\sphinxupquote{Gt}}, \sphinxcode{\sphinxupquote{Minus}}, \sphinxcode{\sphinxupquote{Lt}}
(\sphinxhref{https://github.com/coq/coq/pull/13986}{\#13986}%
\begin{footnote}[205]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13986}
%
\end{footnote},
by Andrej Dudenhefner).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
Unsigned primitive integers are now named \sphinxcode{\sphinxupquote{uint63}} instead of \sphinxcode{\sphinxupquote{int63}}.
The \sphinxcode{\sphinxupquote{Int63}} module is replaced by \sphinxcode{\sphinxupquote{Uint63}}. The full list of changes
is described in the PR.
(\sphinxhref{https://github.com/coq/coq/pull/13895}{\#13895}%
\begin{footnote}[206]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13895}
%
\end{footnote},
by Ana Borges).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{leb}} and \sphinxcode{\sphinxupquote{ltb}} functions for \sphinxcode{\sphinxupquote{ascii}}
(\sphinxhref{https://github.com/coq/coq/pull/13080}{\#13080}%
\begin{footnote}[207]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13080}
%
\end{footnote},
by Yishuai Li).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Library for signed primitive integers, Sint63. The following operations were added to the kernel: division, remainder, comparison functions, and arithmetic shift right. Everything else works the same for signed and unsigned ints.
(\sphinxhref{https://github.com/coq/coq/pull/13559}{\#13559}%
\begin{footnote}[208]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13559}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12109}{\#12109}%
\begin{footnote}[209]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12109}
%
\end{footnote},
by Ana Borges, Guillaume Melquiond and Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas about vectors related with \sphinxcode{\sphinxupquote{to\_list}}: \sphinxcode{\sphinxupquote{length\_to\_list}}, \sphinxcode{\sphinxupquote{of\_list\_to\_list\_opp}}, \sphinxcode{\sphinxupquote{to\_list\_nil}}, \sphinxcode{\sphinxupquote{to\_list\_cons}}, \sphinxcode{\sphinxupquote{to\_list\_hd}}, \sphinxcode{\sphinxupquote{to\_list\_last}}, \sphinxcode{\sphinxupquote{to\_list\_const}}, \sphinxcode{\sphinxupquote{to\_list\_nth\_order}}, \sphinxcode{\sphinxupquote{to\_list\_tl}}, \sphinxcode{\sphinxupquote{to\_list\_append}}, \sphinxcode{\sphinxupquote{to\_list\_rev\_append\_tail}}, \sphinxcode{\sphinxupquote{to\_list\_rev\_append}}, \sphinxcode{\sphinxupquote{to\_list\_rev}}, \sphinxcode{\sphinxupquote{to\_list\_map}}, \sphinxcode{\sphinxupquote{to\_list\_fold\_left}}, \sphinxcode{\sphinxupquote{to\_list\_fold\_right}}, \sphinxcode{\sphinxupquote{to\_list\_Forall}}, \sphinxcode{\sphinxupquote{to\_list\_Exists}}, \sphinxcode{\sphinxupquote{to\_list\_In}}, \sphinxcode{\sphinxupquote{to\_list\_Forall2}}
(\sphinxhref{https://github.com/coq/coq/pull/13671}{\#13671}%
\begin{footnote}[210]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13671}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas about \sphinxcode{\sphinxupquote{count\_occ}}: \sphinxcode{\sphinxupquote{count\_occ\_app}}, \sphinxcode{\sphinxupquote{count\_occ\_elt\_eq}}, \sphinxcode{\sphinxupquote{count\_occ\_elt\_neq}}, \sphinxcode{\sphinxupquote{count\_occ\_bound}}, \sphinxcode{\sphinxupquote{count\_occ\_repeat\_eq}}, \sphinxcode{\sphinxupquote{count\_occ\_repeat\_neq}}, \sphinxcode{\sphinxupquote{count\_occ\_unique}}, \sphinxcode{\sphinxupquote{count\_occ\_repeat\_excl}}, \sphinxcode{\sphinxupquote{count\_occ\_sgt}}, \sphinxcode{\sphinxupquote{Permutation\_count\_occ}}
(\sphinxhref{https://github.com/coq/coq/pull/13804}{\#13804}%
\begin{footnote}[211]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13804}
%
\end{footnote},
by Olivier Laurent with help of Jean\sphinxhyphen{}Christophe Léchenet).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas to \sphinxcode{\sphinxupquote{List}}: \sphinxcode{\sphinxupquote{Exists\_map}}, \sphinxcode{\sphinxupquote{Exists\_concat}}, \sphinxcode{\sphinxupquote{Exists\_flat\_map}}, \sphinxcode{\sphinxupquote{Forall\_map}}, \sphinxcode{\sphinxupquote{Forall\_concat}}, \sphinxcode{\sphinxupquote{Forall\_flat\_map}}, \sphinxcode{\sphinxupquote{nth\_error\_map}}, \sphinxcode{\sphinxupquote{nth\_repeat}}, \sphinxcode{\sphinxupquote{nth\_error\_repeat}}
(\sphinxhref{https://github.com/coq/coq/pull/13955}{\#13955}%
\begin{footnote}[212]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13955}
%
\end{footnote},
by Andrej Dudenhefner, with help from Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{Cantor.v}} containing the Cantor pairing function and its inverse.
\sphinxcode{\sphinxupquote{Cantor.to\_nat : nat * nat \sphinxhyphen{}> nat}} and \sphinxcode{\sphinxupquote{Cantor.of\_nat : nat \sphinxhyphen{}> nat * nat}}
are the respective bijections between \sphinxcode{\sphinxupquote{nat * nat}} and \sphinxcode{\sphinxupquote{nat}}.
(\sphinxhref{https://github.com/coq/coq/pull/14008}{\#14008}%
\begin{footnote}[213]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14008}
%
\end{footnote},
by Andrej Dudenhefner).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas to \sphinxcode{\sphinxupquote{Q}}: \sphinxcode{\sphinxupquote{Qeq\_from\_parts}}, \sphinxcode{\sphinxupquote{Qden\_cancel}}, \sphinxcode{\sphinxupquote{Qnum\_cancel}}, \sphinxcode{\sphinxupquote{Qreduce\_l}}, \sphinxcode{\sphinxupquote{Qreduce\_r}}, \sphinxcode{\sphinxupquote{Qmult\_inject\_Z\_l}}, \sphinxcode{\sphinxupquote{Qmult\_inject\_Z\_r}} QArith\_base
Reduction of rationals; establishing equality for Qden/Qnum separately.
(\sphinxhref{https://github.com/coq/coq/pull/14087}{\#14087}%
\begin{footnote}[214]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14087}
%
\end{footnote},
by Karolin Varner).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{Coq.Structures.OrdersEx.String\_as\_OT}} and
\sphinxcode{\sphinxupquote{Coq.Structures.OrdersEx.Ascii\_as\_OT}} to make strings and ascii ordered
types (using lexical order).  (\sphinxhref{https://github.com/coq/coq/pull/14096}{\#14096}%
\begin{footnote}[215]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14096}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas \sphinxcode{\sphinxupquote{\DUrole{name}{app\_eq\_app}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Forall\_nil\_iff}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Forall\_cons\_iff}}} to \sphinxcode{\sphinxupquote{List.v}}
(\sphinxhref{https://github.com/coq/coq/pull/14153}{\#14153}%
\begin{footnote}[216]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14153}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/1803}{\#1803}%
\begin{footnote}[217]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/1803}
%
\end{footnote},
by Andrej Dudenhefner, with help from Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{Z}}, \sphinxcode{\sphinxupquote{positive}} and \sphinxcode{\sphinxupquote{N}} constants can now be printed in hexadecimal by
opening \sphinxcode{\sphinxupquote{hex\_Z\_scope}}, \sphinxcode{\sphinxupquote{hex\_positive\_scope}}, and \sphinxcode{\sphinxupquote{hex\_N\_scope}}
respectively (\sphinxhref{https://github.com/coq/coq/pull/14263}{\#14263}%
\begin{footnote}[218]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14263}
%
\end{footnote}, by Jason
Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Absolute value function for Sint63.
(\sphinxhref{https://github.com/coq/coq/pull/14384}{\#14384}%
\begin{footnote}[219]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14384}
%
\end{footnote},
by Ana Borges).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas showing \sphinxcode{\sphinxupquote{\DUrole{name}{firstn}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{skipn}}} commute with \sphinxcode{\sphinxupquote{\DUrole{name}{map}}}.
(\sphinxhref{https://github.com/coq/coq/pull/14406}{\#14406}%
\begin{footnote}[220]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14406}
%
\end{footnote},
by Rudy Peterson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Haskell extraction is now compatible with GHC versions >= 9.0.  Some \sphinxcode{\sphinxupquote{\#if}}
statements have been added to extract \sphinxcode{\sphinxupquote{unsafeCoerce}} to its new location in
newer versions of GHC.  (\sphinxhref{https://github.com/coq/coq/pull/14345}{\#14345}%
\begin{footnote}[221]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14345}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14256}{\#14256}%
\begin{footnote}[222]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14256}
%
\end{footnote}, by Jason Gross).

\end{itemize}


\subparagraph{Infrastructure and dependencies}
\label{\detokenize{changes:id163}}\begin{quote}
\phantomsection\label{\detokenize{changes:dune}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Coq's configure script now requires absolute paths for the \sphinxcode{\sphinxupquote{\sphinxhyphen{}prefix}}
option.
(\sphinxhref{https://github.com/coq/coq/pull/12567}{\#12567}%
\begin{footnote}[223]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12567}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The regular Coq package has been split in two: coq\sphinxhyphen{}core, with
OCaml\sphinxhyphen{}based libraries and tools; and coq\sphinxhyphen{}stdlib, which contains the
Gallina\sphinxhyphen{}based standard library. The package Coq now depends on both
for compatiblity.
(\sphinxhref{https://github.com/coq/coq/pull/12567}{\#12567}%
\begin{footnote}[224]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12567}
%
\end{footnote},
by Emilio Jesus Gallego Arias, review by Vincent Laporte, Guillaume
Melquiond, Enrico Tassi, and Théo Zimmerman).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Coq's OCaml parts and tools {[}coq\sphinxhyphen{}core{]} are now built using Dune.
The main user\sphinxhyphen{}facing change is that Dune >= 2.5 is now required to
build Coq, most recent Dune is usually recommended.
For developers and plugin authors, see the entry in
\sphinxcode{\sphinxupquote{dev/doc/changes.md}}.
(\sphinxhref{https://github.com/coq/coq/pull/13617}{\#13617}%
\begin{footnote}[225]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13617}
%
\end{footnote},
by Emilio Jesús Gallego Arias, Rudi Grinberg, and Théo Zimmerman;
review and testing by Gaëtan Gilbert, Guillaume Melquiond, and
Enrico Tassi)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Undocumented variables \sphinxcode{\sphinxupquote{OLDROOT}} and \sphinxcode{\sphinxupquote{COQPREFIXINSTALL}} which
added a prefix path to \sphinxcode{\sphinxupquote{make install}} have been removed. Now, \sphinxcode{\sphinxupquote{make
install}} does support the more standard \sphinxcode{\sphinxupquote{DESTDIR}} variable, akin
to what \sphinxcode{\sphinxupquote{coq\_makefile}} does.
(\sphinxhref{https://github.com/coq/coq/pull/14258}{\#14258}%
\begin{footnote}[226]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14258}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Support OCaml 4.12
(\sphinxhref{https://github.com/coq/coq/pull/13885}{\#13885}%
\begin{footnote}[227]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13885}
%
\end{footnote},
by Emilio Jesus Gallego Arias, review by Gaëtan Gilbert and Théo Zimmerman).

\end{itemize}


\subparagraph{Miscellaneous}
\label{\detokenize{changes:id169}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The representation of micromega caches was slightly
altered for efficiency purposes. As a consequence
all stale caches must be cleaned up
(\sphinxhref{https://github.com/coq/coq/pull/13405}{\#13405}%
\begin{footnote}[228]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13405}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Fix the timeout facility on Unix to allow for nested timeouts.
Previous behavior on nested timeouts was that an "inner" timeout would replace an "outer"
timeout, so that the outer timeout would no longer fire. With the new behavior, Unix and Windows
implementations should be (approximately) equivalent.
(\sphinxhref{https://github.com/coq/coq/pull/13586}{\#13586}%
\begin{footnote}[229]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13586}
%
\end{footnote},
by Lasse Blaauwbroek).

\end{itemize}


\paragraph{Changes in 8.14.1}
\label{\detokenize{changes:changes-in-8-14-1}}

\subparagraph{Kernel}
\label{\detokenize{changes:id172}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Fix the implementation of persistent arrays used by the VM and native compute
so that it uses a uniform representation. Previously, storing primitive floats
inside primitive arrays could cause memory corruption
(\sphinxhref{https://github.com/coq/coq/pull/15081}{\#15081}%
\begin{footnote}[230]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/15081}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/15070}{\#15070}%
\begin{footnote}[231]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/15070}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}


\subparagraph{Specification language, type inference}
\label{\detokenize{changes:id175}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Missing registration of universe constraints in {\hyperref[\detokenize{language/core/modules:coq:cmd.Module-Type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module Type}}}}} elaboration
(\sphinxhref{https://github.com/coq/coq/pull/14666}{\#14666}%
\begin{footnote}[232]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14666}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14505}{\#14505}%
\begin{footnote}[233]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14505}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Tactics}
\label{\detokenize{changes:id178}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}} more robust with respect to Ltac \sphinxcode{\sphinxupquote{constr}} bindings containing
existential variables
(\sphinxhref{https://github.com/coq/coq/pull/14671}{\#14671}%
\begin{footnote}[234]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14671}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10796}{\#10796}%
\begin{footnote}[235]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10796}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
correct support of trailing \sphinxcode{\sphinxupquote{\DUrole{notation}{let}}} by tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.specialize}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specialize}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/15046}{\#15046}%
\begin{footnote}[236]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/15046}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/15043}{\#15043}%
\begin{footnote}[237]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/15043}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Commands and options}
\label{\detokenize{changes:id183}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
anomaly with {\hyperref[\detokenize{addendum/extraction:coq:flag.Extraction-Conservative-Types}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Conservative Types}}}}} when extracting
pattern\sphinxhyphen{}matching on singleton types
(\sphinxhref{https://github.com/coq/coq/pull/14669}{\#14669}%
\begin{footnote}[238]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14669}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/3527}{\#3527}%
\begin{footnote}[239]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/3527}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
a regular error instead of an anomaly when calling {\hyperref[\detokenize{addendum/extraction:coq:cmd.Separate-Extraction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Separate
Extraction}}}}} in a module
(\sphinxhref{https://github.com/coq/coq/pull/14670}{\#14670}%
\begin{footnote}[240]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14670}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10796}{\#10796}%
\begin{footnote}[241]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10796}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subsubsection{Version 8.13}
\label{\detokenize{changes:version-8-13}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id188}}
\sphinxAtStartPar
Coq version 8.13 integrates many usability improvements, as well
as extensions of the core language.
The main changes include:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{changes:primarrays}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction}}}} of {\hyperref[\detokenize{language/core/primitive:primitive-arrays}]{\sphinxcrossref{\DUrole{std,std-ref}{primitive persistent arrays}}}}
in the core language, implemented using imperative persistent arrays.

\item {} 
\sphinxAtStartPar
Introduction of {\hyperref[\detokenize{changes:uip}]{\sphinxcrossref{\DUrole{std,std-ref}{definitional proof irrelevance}}}} for the equality type
defined in the SProp sort.

\item {} 
\sphinxAtStartPar
Cumulative record and inductive type declarations can now
{\hyperref[\detokenize{changes:variancedecl}]{\sphinxcrossref{\DUrole{std,std-ref}{specify}}}} the variance of their universes.

\item {} 
\sphinxAtStartPar
Various bugfixes and uniformization of behavior with respect to the use of
implicit arguments and the handling of existential variables in
declarations, unification and tactics.

\item {} 
\sphinxAtStartPar
New warning for {\hyperref[\detokenize{changes:unusedvar}]{\sphinxcrossref{\DUrole{std,std-ref}{unused variables}}}} in catch\sphinxhyphen{}all match
branches that match multiple distinct patterns.

\item {} 
\sphinxAtStartPar
New {\hyperref[\detokenize{changes:hintwarning}]{\sphinxcrossref{\DUrole{std,std-ref}{warning}}}} for \sphinxcode{\sphinxupquote{Hint}} commands outside
sections without a locality attribute, whose goal is to eventually
remove the fragile default behavior of importing hints only when
using \sphinxcode{\sphinxupquote{Require}}. The recommended fix is to declare hints as \sphinxcode{\sphinxupquote{export}},
instead of the current default \sphinxcode{\sphinxupquote{global}}, meaning that they are imported
through \sphinxcode{\sphinxupquote{Require Import}} only, not \sphinxcode{\sphinxupquote{Require}}.
See the following \sphinxhref{https://coq.discourse.group/t/change-of-default-locality-for-hint-commands-in-coq-8-13/1140}{rationale and guidelines}%
\begin{footnote}[242]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.discourse.group/t/change-of-default-locality-for-hint-commands-in-coq-8-13/1140}
%
\end{footnote}
for details.

\item {} 
\sphinxAtStartPar
General support for {\hyperref[\detokenize{changes:booleanattrs}]{\sphinxcrossref{\DUrole{std,std-ref}{boolean attributes}}}}.

\item {} 
\sphinxAtStartPar
Many improvements to the handling of {\hyperref[\detokenize{changes:id232}]{\sphinxcrossref{\DUrole{std,std-ref}{notations}}}},
including number notations, recursive notations and notations with bindings.
A new algorithm chooses the most precise notation available to print an expression,
which might introduce changes in printing behavior.

\item {} 
\sphinxAtStartPar
Tactic {\hyperref[\detokenize{changes:id265}]{\sphinxcrossref{\DUrole{std,std-ref}{improvements}}}} in {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} and its {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} preprocessing step,
now supporting reasoning on boolean operators such as \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{leb}}} and supporting
primitive integers \sphinxcode{\sphinxupquote{\DUrole{name}{Int63}}}.

\item {} 
\sphinxAtStartPar
Typing flags can now be specified {\hyperref[\detokenize{changes:typingflags}]{\sphinxcrossref{\DUrole{std,std-ref}{per\sphinxhyphen{}constant / inductive}}}}.

\item {} 
\sphinxAtStartPar
Improvements to the reference manual including updated syntax
descriptions that match Coq's grammar in several chapters, and splitting parts of
the tactics chapter to independent sections.

\end{itemize}

\sphinxAtStartPar
See the {\hyperref[\detokenize{changes:changes-in-8-13-beta1}]{\sphinxcrossref{Changes in 8.13+beta1}}} section and following sections for the
detailed list of changes, including potentially breaking changes marked
with \sphinxstylestrong{Changed}.

\sphinxAtStartPar
Coq's documentation is available at \sphinxurl{https://coq.github.io/doc/v8.13/refman} (reference
manual), and \sphinxurl{https://coq.github.io/doc/v8.13/stdlib} (documentation of
the standard library). Developer documentation of the ML API is available
at \sphinxurl{https://coq.github.io/doc/v8.13/api}.

\sphinxAtStartPar
Maxime Dénès, Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop and Théo Zimmermann worked on maintaining and improving the
continuous integration system and package building infrastructure.

\sphinxAtStartPar
Erik Martin\sphinxhyphen{}Dorel has maintained the \sphinxhref{https://hub.docker.com/r/coqorg/coq}{Coq Docker images}%
\begin{footnote}[243]\sphinxAtStartFootnote
\sphinxnolinkurl{https://hub.docker.com/r/coqorg/coq}
%
\end{footnote} that are used in many Coq
projects for continuous integration.

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

\sphinxAtStartPar
Our current 32 maintainers are Yves Bertot, Frédéric Besson, Tej
Chajed, Cyril Cohen, Pierre Corbineau, Pierre Courtieu, Maxime Dénès,
Jim Fehrle, Julien Forest, Emilio Jesús Gallego Arias, Gaëtan Gilbert,
Georges Gonthier, Benjamin Grégoire, Jason Gross, Hugo Herbelin,
Vincent Laporte, Olivier Laurent, Assia Mahboubi, Kenji Maillard,
Guillaume Melquiond, Pierre\sphinxhyphen{}Marie Pédrot, Clément Pit\sphinxhyphen{}Claudel,
Kazuhiko Sakaguchi, Vincent Semeria, Michael Soegtrop, Arnaud Spiwack,
Matthieu Sozeau, Enrico Tassi, Laurent Théry, Anton Trunov, Li\sphinxhyphen{}yao Xia
and Théo Zimmermann.

\sphinxAtStartPar
The 51 contributors to this version are Reynald Affeldt, Tanaka Akira, Frédéric
Besson, Lasse Blaauwbroek, Clément Blaudeau, Martin Bodin, Ali Caglayan, Tej Chajed,
Cyril Cohen, Julien Coolen, Matthew Dempsky, Maxime Dénès, Andres Erbsen,
Jim Fehrle, Emilio Jesús Gallego Arias, Paolo G. Giarrusso, Attila Gáspár, Gaëtan Gilbert,
Jason Gross, Benjamin Grégoire, Hugo Herbelin, Wolf Honore, Jasper Hugunin, Ignat Insarov,
Ralf Jung, Fabian Kunze, Vincent Laporte, Olivier Laurent, Larry D. Lee Jr,
Thomas Letan, Yishuai Li, James Lottes, Jean\sphinxhyphen{}Christophe Léchenet,
Kenji Maillard, Erik Martin\sphinxhyphen{}Dorel, Yusuke Matsushita, Guillaume Melquiond,
Carl Patenaude\sphinxhyphen{}Poulin, Clément Pit\sphinxhyphen{}Claudel, Pierre\sphinxhyphen{}Marie Pédrot, Pierre Roux,
Kazuhiko Sakaguchi, Vincent Semeria, Michael Soegtrop, Matthieu Sozeau,
Enrico Tassi, Anton Trunov, Edward Wang, Li\sphinxhyphen{}yao Xia, Beta Ziliani and Théo Zimmermann.

\sphinxAtStartPar
The Coq community at large helped improve the design of this new version via
the GitHub issue and pull request system, the Coq development mailing list
\sphinxhref{mailto:coqdev@inria.fr}{coqdev@inria.fr}, the \sphinxhref{mailto:coq-club@inria.fr}{coq\sphinxhyphen{}club@inria.fr} mailing list, the \sphinxhref{https://coq.discourse.group/}{Discourse forum}%
\begin{footnote}[244]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.discourse.group/}
%
\end{footnote} and the \sphinxhref{http://coq.zulipchat.com}{Coq Zulip chat}%
\begin{footnote}[245]\sphinxAtStartFootnote
\sphinxnolinkurl{http://coq.zulipchat.com}
%
\end{footnote}.

\sphinxAtStartPar
Version 8.13's development spanned 5 months from the release of
Coq 8.12.0. Enrico Tassi and Maxime Dénès are the release managers of Coq 8.13.
This release is the result of 400 merged PRs, closing \textasciitilde{}100 issues.

\begin{DUlineblock}{0em}
\item[] Nantes, November 2020,
\item[] Matthieu Sozeau for the Coq development team
\item[] 
\end{DUlineblock}


\paragraph{Changes in 8.13+beta1}
\label{\detokenize{changes:changes-in-8-13-beta1}}
\begin{sphinxShadowBox}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id968}}{\hyperref[\detokenize{changes:id193}]{\sphinxcrossref{Kernel}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id969}}{\hyperref[\detokenize{changes:id203}]{\sphinxcrossref{Specification language, type inference}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id970}}{\hyperref[\detokenize{changes:id232}]{\sphinxcrossref{Notations}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id971}}{\hyperref[\detokenize{changes:id265}]{\sphinxcrossref{Tactics}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id972}}{\hyperref[\detokenize{changes:id286}]{\sphinxcrossref{Tactic language}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id973}}{\hyperref[\detokenize{changes:id292}]{\sphinxcrossref{SSReflect}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id974}}{\hyperref[\detokenize{changes:id296}]{\sphinxcrossref{Commands and options}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id975}}{\hyperref[\detokenize{changes:tools}]{\sphinxcrossref{Tools}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id976}}{\hyperref[\detokenize{changes:id314}]{\sphinxcrossref{CoqIDE}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id977}}{\hyperref[\detokenize{changes:id317}]{\sphinxcrossref{Standard library}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id978}}{\hyperref[\detokenize{changes:id332}]{\sphinxcrossref{Infrastructure and dependencies}}}

\end{itemize}
\end{sphinxShadowBox}


\subparagraph{Kernel}
\label{\detokenize{changes:id193}}\begin{quote}
\phantomsection\label{\detokenize{changes:uip}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Definitional UIP, only when {\hyperref[\detokenize{addendum/sprop:coq:flag.Definitional-UIP}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definitional UIP}}}}} is enabled.
This models definitional uniqueness of identity proofs for the equality
type in SProp. It is deactivated by default as it can lead to
non\sphinxhyphen{}termination in combination with impredicativity.
Use of this flag is also printed by {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Print-Assumptions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Assumptions}}}}}. See
documentation of the flag for details.
(\sphinxhref{https://github.com/coq/coq/pull/10390}{\#10390}%
\begin{footnote}[246]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10390}
%
\end{footnote},
by Gaëtan Gilbert).

\phantomsection\label{\detokenize{changes:primarrays}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Built\sphinxhyphen{}in support for persistent arrays, which expose a functional
interface but are implemented using an imperative data structure, for
better performance.
(\sphinxhref{https://github.com/coq/coq/pull/11604}{\#11604}%
\begin{footnote}[247]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11604}
%
\end{footnote},
by Maxime Dénès and Benjamin Grégoire, with help from Gaëtan Gilbert).

\sphinxAtStartPar
Primitive arrays are irrelevant in their single
polymorphic universe (same as a polymorphic cumulative list
inductive would be) (\sphinxhref{https://github.com/coq/coq/pull/13356}{\#13356}%
\begin{footnote}[248]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13356}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/13354}{\#13354}%
\begin{footnote}[249]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13354}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
A loss of definitional equality for declarations obtained through
{\hyperref[\detokenize{language/core/modules:coq:cmd.Include}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Include}}}}} when entering the scope of a {\hyperref[\detokenize{language/core/modules:coq:cmd.Module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module}}}}} or
{\hyperref[\detokenize{language/core/modules:coq:cmd.Module-Type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module Type}}}}} was causing {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} not to see the included
declarations
(\sphinxhref{https://github.com/coq/coq/pull/12537}{\#12537}%
\begin{footnote}[250]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12537}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/pull/12525}{\#12525}%
\begin{footnote}[251]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12525}
%
\end{footnote} and \sphinxhref{https://github.com/coq/coq/pull/12647}{\#12647}%
\begin{footnote}[252]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12647}
%
\end{footnote}, by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Fix an incompleteness in the typechecking of \sphinxcode{\sphinxupquote{match}} for
cumulative inductive types. This could result in breaking subject
reduction.
(\sphinxhref{https://github.com/coq/coq/pull/13501}{\#13501}%
\begin{footnote}[253]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13501}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13495}{\#13495}%
\begin{footnote}[254]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13495}
%
\end{footnote},
by Matthieu Sozeau).

\end{itemize}


\subparagraph{Specification language, type inference}
\label{\detokenize{changes:id203}}\begin{quote}
\phantomsection\label{\detokenize{changes:booleanattrs}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
{\hyperref[\detokenize{language/core/basic:term-boolean-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{Boolean attributes}}}} are now specified using
key/value pairs, that is to say \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{attr}}$}}}}\DUrole{repeat-wrapper}{\DUrole{repeat}{= \DUrole{alternative}{\DUrole{alternative-block}{yes}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{no}}}\DUrole{notation-sup}{?}}}}}.
If the value is missing, the default is \sphinxcode{\sphinxupquote{\DUrole{notation}{yes}}}.  The old syntax is still
supported, but produces the \sphinxcode{\sphinxupquote{deprecated\sphinxhyphen{}attribute\sphinxhyphen{}syntax}} warning.

\sphinxAtStartPar
Deprecated attributes are {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(monomorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(monomorphic)}}}}},
{\hyperref[\detokenize{language/core/inductive:coq:attr.universes(notemplate)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(notemplate)}}}}} and {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(noncumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(noncumulative)}}}}}, which are
respectively replaced by {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic=no)}}}}},
{\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template=no)}}}}}
and {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative=no)}}}}}.
Attributes {\hyperref[\detokenize{addendum/program:coq:attr.program}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{program}}}}} and {\hyperref[\detokenize{language/extensions/canonical:coq:attr.canonical}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{canonical}}}}} are also affected,
with the syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{attr}}$}}}}(false)}}} being deprecated in favor of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{attr}}$}}}}=no}}}.
(\sphinxhref{https://github.com/coq/coq/pull/13312}{\#13312}%
\begin{footnote}[255]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13312}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} Heuristics for universe minimization to \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}: also
use constraints \sphinxcode{\sphinxupquote{Prop <= i}} (\sphinxhref{https://github.com/coq/coq/pull/10331}{\#10331}%
\begin{footnote}[256]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10331}
%
\end{footnote}, by Gaëtan Gilbert with
help from Maxime Dénès and Matthieu Sozeau, fixes \sphinxhref{https://github.com/coq/coq/issues/12414}{\#12414}%
\begin{footnote}[257]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12414}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} The type given to {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} is no longer automatically
generalized over unbound and {\hyperref[\detokenize{language/extensions/implicit-arguments:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{generalizable}}}} variables.
Use \sphinxcode{\sphinxupquote{Instance : `\{type\}}} instead of \sphinxcode{\sphinxupquote{\DUrole{notation}{Instance : {\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} to get the old behaviour, or
enable the compatibility flag {\hyperref[\detokenize{addendum/type-classes:coq:flag.Instance-Generalized-Output}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance Generalized Output}}}}}.
(\sphinxhref{https://github.com/coq/coq/pull/13188}{\#13188}%
\begin{footnote}[258]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13188}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/6042}{\#6042}%
\begin{footnote}[259]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/6042}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Tweaked the algorithm giving default names to arguments.
Should reduce the frequency that argument names get an
unexpected suffix.
Also makes {\hyperref[\detokenize{proof-engine/tactics:coq:flag.Mangle-Names}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Mangle Names}}}}} not mess up argument names.
(\sphinxhref{https://github.com/coq/coq/pull/12756}{\#12756}%
\begin{footnote}[260]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12756}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12001}{\#12001}%
\begin{footnote}[261]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12001}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/6785}{\#6785}%
\begin{footnote}[262]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/6785}
%
\end{footnote},
by Jasper Hugunin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Undocumented and experimental forward class hint feature \sphinxcode{\sphinxupquote{:>>}}.
Use \sphinxcode{\sphinxupquote{:>}} (see \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-of_type}]{\sphinxcrossref{\DUrole{hole}{of\_type}}}}}}}) instead
(\sphinxhref{https://github.com/coq/coq/pull/13106}{\#13106}%
\begin{footnote}[263]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13106}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\phantomsection\label{\detokenize{changes:variancedecl}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:} Commands {\hyperref[\detokenize{language/core/inductive:coq:cmd.Inductive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Inductive}}}}}, {\hyperref[\detokenize{language/core/records:coq:cmd.Record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} and synonyms now
support syntax \sphinxcode{\sphinxupquote{Inductive foo@\{=i +j *k l\}}} to specify variance
information for their universes (in {\hyperref[\detokenize{addendum/universe-polymorphism:cumulative}]{\sphinxcrossref{\DUrole{std,std-ref}{Cumulative}}}}
mode) (\sphinxhref{https://github.com/coq/coq/pull/12653}{\#12653}%
\begin{footnote}[264]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12653}
%
\end{footnote}, by Gaëtan
Gilbert).

\phantomsection\label{\detokenize{changes:unusedvar}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Warning on unused variables in pattern\sphinxhyphen{}matching branches of
\sphinxcode{\sphinxupquote{\DUrole{notation}{match}}} serving as catch\sphinxhyphen{}all branches for at least two distinct
patterns.
(\sphinxhref{https://github.com/coq/coq/pull/12768}{\#12768}%
\begin{footnote}[265]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12768}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12762}{\#12762}%
\begin{footnote}[266]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12762}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Definition and (Co)Fixpoint now support the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:attr.using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{using}}}}} attribute.
It has the same effect as {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof-using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof using}}}}}, which is only available in
interactive mode.
(\sphinxhref{https://github.com/coq/coq/pull/13183}{\#13183}%
\begin{footnote}[267]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13183}
%
\end{footnote},
by Enrico Tassi).

\phantomsection\label{\detokenize{changes:typingflags}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Typing flags can now be specified per\sphinxhyphen{}constant / inductive, this
allows to fine\sphinxhyphen{}grain specify them from plugins or attributes. See
{\hyperref[\detokenize{proof-engine/vernacular-commands:controlling-typing-flags}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling Typing Flags}}}} for details on attribute syntax.
(\sphinxhref{https://github.com/coq/coq/pull/12586}{\#12586}%
\begin{footnote}[268]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12586}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Inference of return predicate of a \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} by inversion takes
sort elimination constraints into account
(\sphinxhref{https://github.com/coq/coq/pull/13290}{\#13290}%
\begin{footnote}[269]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13290}
%
\end{footnote},
grants \sphinxhref{https://github.com/coq/coq/issues/13278}{\#13278}%
\begin{footnote}[270]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13278}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Implicit arguments taken into account in defined fields of a record type declaration
(\sphinxhref{https://github.com/coq/coq/pull/13166}{\#13166}%
\begin{footnote}[271]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13166}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13165}{\#13165}%
\begin{footnote}[272]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13165}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Allow use of typeclass inference for the return predicate of a \sphinxcode{\sphinxupquote{\DUrole{notation}{match}}}
(was deactivated in versions 8.10 to 8.12, \sphinxhref{https://github.com/coq/coq/pull/13217}{\#13217}%
\begin{footnote}[273]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13217}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13216}{\#13216}%
\begin{footnote}[274]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13216}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
A case of unification raising an anomaly IllTypedInstance
(\sphinxhref{https://github.com/coq/coq/pull/13376}{\#13376}%
\begin{footnote}[275]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13376}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13266}{\#13266}%
\begin{footnote}[276]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13266}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Using \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{wf ...\}}}}} in local fixpoints is an error, not an anomaly
(\sphinxhref{https://github.com/coq/coq/pull/13383}{\#13383}%
\begin{footnote}[277]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13383}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11816}{\#11816}%
\begin{footnote}[278]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11816}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Issue when two expressions involving different projections and one is
primitive need to be unified
(\sphinxhref{https://github.com/coq/coq/pull/13386}{\#13386}%
\begin{footnote}[279]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13386}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9971}{\#9971}%
\begin{footnote}[280]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9971}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
A bug producing ill\sphinxhyphen{}typed instances of existential variables when let\sphinxhyphen{}ins
interleaved with assumptions
(\sphinxhref{https://github.com/coq/coq/pull/13387}{\#13387}%
\begin{footnote}[281]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13387}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13387}{\#12348}%
\begin{footnote}[282]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13387}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Notations}
\label{\detokenize{changes:id232}}\label{\detokenize{changes:id233}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
In notations (except in custom entries), the misleading \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-syntax_modifier}]{\sphinxcrossref{\DUrole{hole}{syntax\_modifier}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} ident}}} (which accepted either an identifier or
a \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}) is deprecated and should be replaced by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} name}}}. If
the intent was really to only parse identifiers, this will
eventually become possible, but only as of Coq 8.15.
In custom entries, the meaning of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} ident}}} is silently changed
from parsing identifiers or \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}} to parsing only identifiers
without warning, but this presumably affects only rare, recent and
relatively experimental code
(\sphinxhref{https://github.com/coq/coq/pull/11841}{\#11841}%
\begin{footnote}[283]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11841}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/pull/9514}{\#9514}%
\begin{footnote}[284]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9514}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Improved support for notations/abbreviations with mixed terms and patterns (such as the forcing modality)
(\sphinxhref{https://github.com/coq/coq/pull/12099}{\#12099}%
\begin{footnote}[285]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12099}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed}
Rational and real constants are parsed differently.
The exponent is now encoded separately from the fractional part
using \sphinxcode{\sphinxupquote{Z.pow\_pos}}. This way, parsing large exponents can no longer
blow up and constants are printed in a form closer to the one in which they
were parsed (i.e., \sphinxcode{\sphinxupquote{102e\sphinxhyphen{}2}} is reprinted as such and not \sphinxcode{\sphinxupquote{1.02}}).
(\sphinxhref{https://github.com/coq/coq/pull/12218}{\#12218}%
\begin{footnote}[286]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12218}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Scope information is propagated in indirect applications to a
reference prefixed with \sphinxcode{\sphinxupquote{\DUrole{operator}{@}}}; this covers for instance the case
\sphinxcode{\sphinxupquote{\DUrole{name}{r}\DUrole{operator}{.(@}\DUrole{name}{p}\DUrole{operator}{)} \DUrole{name}{t}}} where scope information from \sphinxcode{\sphinxupquote{\DUrole{name}{p}}} is now taken into
account for interpreting \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} (\sphinxhref{https://github.com/coq/coq/pull/12685}{\#12685}%
\begin{footnote}[287]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12685}
%
\end{footnote}, by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
New model for \sphinxcode{\sphinxupquote{only parsing}} and \sphinxcode{\sphinxupquote{only printing}} notations with
support for at most one parsing\sphinxhyphen{}and\sphinxhyphen{}printing or only\sphinxhyphen{}parsing
notation per notation and scope, but an arbitrary number of
only\sphinxhyphen{}printing notations
(\sphinxhref{https://github.com/coq/coq/pull/12950}{\#12950}%
\begin{footnote}[288]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12950}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/4738}{\#4738}%
\begin{footnote}[289]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4738}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/9682}{\#9682}%
\begin{footnote}[290]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9682}
%
\end{footnote}
and part 2 of \sphinxhref{https://github.com/coq/coq/issues/12908}{\#12908}%
\begin{footnote}[291]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12908}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Redeclaring a notation also reactivates its printing rule; in
particular a second {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} of the same module reactivates the
printing rules declared in this module. In theory, this leads to
changes in behavior for printing. However, this is mitigated in
general by the adoption in \sphinxhref{https://github.com/coq/coq/pull/12986}{\#12986}%
\begin{footnote}[292]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12986}
%
\end{footnote} of a priority given to
notations which match a larger part of the term to print
(\sphinxhref{https://github.com/coq/coq/pull/12984}{\#12984}%
\begin{footnote}[293]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12984}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/7443}{\#7443}%
\begin{footnote}[294]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7443}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/10824}{\#10824}%
\begin{footnote}[295]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10824}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Use of notations for printing now gives preference
to notations which match a larger part of the term to abbreviate
(\sphinxhref{https://github.com/coq/coq/pull/12986}{\#12986}%
\begin{footnote}[296]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12986}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed}
OCaml parser and printer for real constants have been removed.
Real constants are now handled with proven Coq code.
(\sphinxhref{https://github.com/coq/coq/pull/12218}{\#12218}%
\begin{footnote}[297]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12218}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated}
\sphinxcode{\sphinxupquote{Numeral.v}} is deprecated, please use \sphinxcode{\sphinxupquote{Number.v}} instead.
(\sphinxhref{https://github.com/coq/coq/pull/12218}{\#12218}%
\begin{footnote}[298]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12218}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
\sphinxcode{\sphinxupquote{Numeral Notation}}, please use {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} instead
(\sphinxhref{https://github.com/coq/coq/pull/12979}{\#12979}%
\begin{footnote}[299]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12979}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{language/coq-library:coq:flag.Printing-Float}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Float}}}}} flag to print primitive floats as hexadecimal
instead of decimal values. This is included in the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-All}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} flag
(\sphinxhref{https://github.com/coq/coq/pull/11986}{\#11986}%
\begin{footnote}[300]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11986}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{user-extensions/syntax-extensions:number-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Number Notation}}}} and {\hyperref[\detokenize{user-extensions/syntax-extensions:string-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{String Notation}}}} commands now
support parameterized inductive and non inductive types
(\sphinxhref{https://github.com/coq/coq/pull/12218}{\#12218}%
\begin{footnote}[301]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12218}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12035}{\#12035}%
\begin{footnote}[302]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12035}
%
\end{footnote},
by Pierre Roux, review by Jason Gross and Jim Fehrle for the
reference manual).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Added support for encoding notations of the form \sphinxcode{\sphinxupquote{\DUrole{name}{x} \DUrole{name,builtin,pseudo}{⪯} \DUrole{name}{y} \DUrole{name,builtin,pseudo}{⪯} \DUrole{operator}{..} \DUrole{name,builtin,pseudo}{⪯} \DUrole{name}{z} \DUrole{name,builtin,pseudo}{⪯} \DUrole{name}{t}}}.
This feature is considered experimental.
(\sphinxhref{https://github.com/coq/coq/pull/12765}{\#12765}%
\begin{footnote}[303]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12765}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}}} entry of {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} can now be used in
notations expecting a single (non\sphinxhyphen{}recursive) binder
(\sphinxhref{https://github.com/coq/coq/pull/13265}{\#13265}%
\begin{footnote}[304]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13265}
%
\end{footnote},
by Hugo Herbelin, see section {\hyperref[\detokenize{user-extensions/syntax-extensions:notations-and-binders}]{\sphinxcrossref{\DUrole{std,std-ref}{Notations and binders}}}} of the
reference manual).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Issues in the presence of notations recursively referring to another
applicative notations, such as missing scope propagation, or failure
to use a notation for printing
(\sphinxhref{https://github.com/coq/coq/pull/12960}{\#12960}%
\begin{footnote}[305]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12960}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9403}{\#9403}%
\begin{footnote}[306]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9403}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/10803}{\#10803}%
\begin{footnote}[307]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10803}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Capture the names of global references by
binders in the presence of notations for binders
(\sphinxhref{https://github.com/coq/coq/pull/12965}{\#12965}%
\begin{footnote}[308]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12965}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9569}{\#9569}%
\begin{footnote}[309]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9569}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Preventing notations for constructors to involve binders
(\sphinxhref{https://github.com/coq/coq/pull/13092}{\#13092}%
\begin{footnote}[310]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13092}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13078}{\#13078}%
\begin{footnote}[311]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13078}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} Notations understand universe names without getting
confused by different imported modules between declaration and use
locations (\sphinxhref{https://github.com/coq/coq/pull/13415}{\#13415}%
\begin{footnote}[312]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13415}
%
\end{footnote}, fixes
\sphinxhref{https://github.com/coq/coq/issues/13303}{\#13303}%
\begin{footnote}[313]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13303}
%
\end{footnote}, by Gaëtan
Gilbert).

\end{itemize}


\subparagraph{Tactics}
\label{\detokenize{changes:id265}}\label{\detokenize{changes:id266}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
In {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}, new existential variables unified with existing ones are no
longer considered as fresh. The behavior of {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple refine}}}}} no longer depends on
the orientation of evar\sphinxhyphen{}evar unification problems, and new existential variables
are always turned into (unshelved) goals. This can break compatibility in
some cases (\sphinxhref{https://github.com/coq/coq/pull/7825}{\#7825}%
\begin{footnote}[314]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7825}
%
\end{footnote}, by Matthieu
Sozeau, with help from Maxime Dénès, review by Pierre\sphinxhyphen{}Marie Pédrot and
Enrico Tassi, fixes \sphinxhref{https://github.com/coq/coq/issues/4095}{\#4095}%
\begin{footnote}[315]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4095}
%
\end{footnote} and
\sphinxhref{https://github.com/coq/coq/issues/4413}{\#4413}%
\begin{footnote}[316]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4413}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Giving an empty list of occurrences after \sphinxcode{\sphinxupquote{\DUrole{notation}{in}}} in tactics is no
longer permitted. Omitting the \sphinxcode{\sphinxupquote{\DUrole{notation}{in}}} gives the same behavior
(\sphinxhref{https://github.com/coq/coq/pull/13236}{\#13237}%
\begin{footnote}[317]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13236}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13235}{\#13235}%
\begin{footnote}[318]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13235}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
\sphinxcode{\sphinxupquote{\DUrole{notation}{at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occs_nums}]{\sphinxcrossref{\DUrole{hole}{occs\_nums}}}}}}} clauses in tactics such as {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}
no longer allow negative values.  A "\sphinxhyphen{}" before the
list (for set complement) is still supported.  Ex: "at \sphinxhyphen{}1 \sphinxhyphen{}2"
is no longer supported but "at \sphinxhyphen{}1 2" is.
(\sphinxhref{https://github.com/coq/coq/pull/13403}{\#13403}%
\begin{footnote}[319]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13403}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
A number of tactics that formerly accepted negative
numbers as parameters now give syntax errors for negative
values.  These include \{e\}constructor, do, timeout,
9 \{e\}auto tactics and psatz*.
(\sphinxhref{https://github.com/coq/coq/pull/13417}{\#13417}%
\begin{footnote}[320]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13417}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
The deprecated and undocumented \sphinxcode{\sphinxupquote{prolog}} tactic was removed
(\sphinxhref{https://github.com/coq/coq/pull/12399}{\#12399}%
\begin{footnote}[321]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12399}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} \sphinxcode{\sphinxupquote{info}} tactic that was deprecated in 8.5.
(\sphinxhref{https://github.com/coq/coq/pull/12423}{\#12423}%
\begin{footnote}[322]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12423}
%
\end{footnote}, by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
Undocumented \sphinxcode{\sphinxupquote{\DUrole{notation}{eauto {\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}} {\hyperref[\detokenize{proof-engine/tactics:grammar-token-nat_or_var}]{\sphinxcrossref{\DUrole{hole}{nat\_or\_var}}}}}}} syntax in favor of new {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.bfs-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bfs eauto}}}}}.
Also deprecated 2\sphinxhyphen{}integer syntax for {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.debug-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{debug eauto}}}}} and {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.info_eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{info\_eauto}}}}}.
(Use {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.bfs-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bfs eauto}}}}} with the {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:flag.Info-Eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Info Eauto}}}}} or {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:flag.Debug-Eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Debug Eauto}}}}} flags instead.)
(\sphinxhref{https://github.com/coq/coq/pull/13381}{\#13381}%
\begin{footnote}[323]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13381}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} is extended to deal with boolean operators e.g. \sphinxcode{\sphinxupquote{andb}} or \sphinxcode{\sphinxupquote{Z.leb}}.
(As \sphinxcode{\sphinxupquote{lia}} gets more powerful, this may break proof scripts relying on \sphinxcode{\sphinxupquote{lia}} failure.)
(\sphinxhref{https://github.com/coq/coq/pull/11906}{\#11906}%
\begin{footnote}[324]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11906}
%
\end{footnote},  by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-_u2026-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply … in}}}}} supports several hypotheses
(\sphinxhref{https://github.com/coq/coq/pull/12246}{\#12246}%
\begin{footnote}[325]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12246}
%
\end{footnote},
by Hugo Herbelin; grants
\sphinxhref{https://github.com/coq/coq/pull/9816}{\#9816}%
\begin{footnote}[326]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9816}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} tactic can now be extended by redefining the \sphinxcode{\sphinxupquote{zify\_pre\_hook}}
tactic. (\sphinxhref{https://github.com/coq/coq/pull/12552}{\#12552}%
\begin{footnote}[327]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12552}
%
\end{footnote},
by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} tactic provides support for primitive integers (module \sphinxcode{\sphinxupquote{\DUrole{name}{ZifyInt63}}}).
(\sphinxhref{https://github.com/coq/coq/pull/12648}{\#12648}%
\begin{footnote}[328]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12648}
%
\end{footnote},  by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Avoid exposing an internal name of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{\_tmp}}} when applying the
\sphinxcode{\sphinxupquote{\DUrole{notation}{\_}}} introduction pattern which would break a dependency
(\sphinxhref{https://github.com/coq/coq/pull/13337}{\#13337}%
\begin{footnote}[329]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13337}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13336}{\#13336}%
\begin{footnote}[330]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13336}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
The case of tactics, such as {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}}, producing existential variables
under binders with an ill\sphinxhyphen{}formed instance
(\sphinxhref{https://github.com/coq/coq/pull/13373}{\#13373}%
\begin{footnote}[331]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13373}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13363}{\#13363}%
\begin{footnote}[332]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13363}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Tactic language}
\label{\detokenize{changes:id286}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
An if\sphinxhyphen{}then\sphinxhyphen{}else syntax to Ltac2
(\sphinxhref{https://github.com/coq/coq/pull/13232}{\#13232}%
\begin{footnote}[333]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13232}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10110}{\#10110}%
\begin{footnote}[334]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10110}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Printing of the quotation qualifiers when printing \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Ltac}}} functions
(\sphinxhref{https://github.com/coq/coq/pull/13028}{\#13028}%
\begin{footnote}[335]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13028}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9716}{\#9716}%
\begin{footnote}[336]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9716}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/13004}{\#13004}%
\begin{footnote}[337]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13004}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{SSReflect}
\label{\detokenize{changes:id292}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
SSReflect intro pattern ltac views \sphinxcode{\sphinxupquote{/{[}dup{]}}}, \sphinxcode{\sphinxupquote{/{[}swap{]}}} and \sphinxcode{\sphinxupquote{/{[}apply{]}}}
(\sphinxhref{https://github.com/coq/coq/pull/13317}{\#13317}%
\begin{footnote}[338]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13317}
%
\end{footnote},
by Cyril Cohen).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Working around a bug of interaction between + and /(ltac:(...)) cf
\sphinxhref{https://github.com/coq/coq/issues/13458}{\#13458}%
\begin{footnote}[339]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13458}
%
\end{footnote}
(\sphinxhref{https://github.com/coq/coq/pull/13459}{\#13459}%
\begin{footnote}[340]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13459}
%
\end{footnote},
by Cyril Cohen).

\end{itemize}


\subparagraph{Commands and options}
\label{\detokenize{changes:id296}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Drop prefixes from grammar non\sphinxhyphen{}terminal names,
e.g. "constr:global" \sphinxhyphen{}> "global", "Prim.name" \sphinxhyphen{}> "name".
Visible in the output of {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Grammar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Grammar}}}}} and {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Custom-Grammar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Custom Grammar}}}}}.
(\sphinxhref{https://github.com/coq/coq/pull/13096}{\#13096}%
\begin{footnote}[341]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13096}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
When declaring arbitrary terms as hints, unsolved
evars are not abstracted implicitly anymore and instead
raise an error
(\sphinxhref{https://github.com/coq/coq/pull/13139}{\#13139}%
\begin{footnote}[342]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13139}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
In the {\hyperref[\detokenize{addendum/extraction:coq:cmd.Extraction-Language}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Language}}}}} command, remove \sphinxcode{\sphinxupquote{Ocaml}} as a valid value.
Use \sphinxcode{\sphinxupquote{OCaml}} instead.  This was deprecated in Coq 8.8, \sphinxhref{https://github.com/coq/coq/pull/6261}{\#6261}%
\begin{footnote}[343]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/6261}
%
\end{footnote}
(\sphinxhref{https://github.com/coq/coq/pull/13016}{\#13016}%
\begin{footnote}[344]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13016}
%
\end{footnote}, by Jim Fehrle).

\phantomsection\label{\detokenize{changes:hintwarning}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
Hint locality currently defaults to {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} in a section and
{\hyperref[\detokenize{language/core/modules:coq:attr.global}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{global}}}}} otherwise, but this will change in a future release.
Hints added outside of sections without an explicit
locality now generate a deprecation warning. We recommend
using {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}} where possible
(\sphinxhref{https://github.com/coq/coq/pull/13384}{\#13384}%
\begin{footnote}[345]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13384}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Grab-Existential-Variables}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Grab Existential Variables}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Existential}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Existential}}}}} commands
(\sphinxhref{https://github.com/coq/coq/pull/12516}{\#12516}%
\begin{footnote}[346]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12516}
%
\end{footnote},
by Maxime Dénès).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}} locality can now be used for all Hint commands,
including {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Cut}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Cut}}}}}, {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Mode}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Mode}}}}}, {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Transparent}}}}} /
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} and
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Remove-Hints}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove Hints}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/13388}{\#13388}%
\begin{footnote}[347]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13388}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Support for automatic insertion of coercions in {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}}
patterns. Additionally, head patterns are now automatically
interpreted as types
(\sphinxhref{https://github.com/coq/coq/pull/13255}{\#13255}%
\begin{footnote}[348]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13255}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13244}{\#13244}%
\begin{footnote}[349]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13244}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Proof-using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof using}}}}} command can now be used without loading the
Ltac plugin (\sphinxcode{\sphinxupquote{\sphinxhyphen{}noinit}} mode)
(\sphinxhref{https://github.com/coq/coq/pull/13339}{\#13339}%
\begin{footnote}[350]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13339}
%
\end{footnote},
by Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Clarify in the documentation that {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Add-ML-Path}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add ML Path}}}}} is not exported to compiled files
(\sphinxhref{https://github.com/coq/coq/pull/13345}{\#13345}%
\begin{footnote}[351]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13345}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13344}{\#13344}%
\begin{footnote}[352]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13344}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Tools}
\label{\detokenize{changes:tools}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Option \sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler}} of the configure script now impacts the
default value of the \sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler}} option of coqc. The
\sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler}} option of the configure script supports a new \sphinxcode{\sphinxupquote{ondemand}}
value, which becomes the default, thus preserving the previous default
behavior.
The stdlib is still precompiled when configuring with \sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler
yes}}. It is not precompiled otherwise.
This an implementation of point 2 of
\sphinxhref{https://github.com/coq/ceps/pull/48}{CEP \#48}%
\begin{footnote}[353]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/ceps/pull/48}
%
\end{footnote}
(\sphinxhref{https://github.com/coq/coq/pull/13352}{\#13352}%
\begin{footnote}[354]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13352}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Added the ability for coq\_makefile to directly set the installation folders,
through the \sphinxcode{\sphinxupquote{COQLIBINSTALL}} and \sphinxcode{\sphinxupquote{COQDOCINSTALL}} variables.
See {\hyperref[\detokenize{practical-tools/utilities:coqmakefilelocal}]{\sphinxcrossref{\DUrole{std,std-ref}{CoqMakefile.local}}}}.
(\sphinxhref{https://github.com/coq/coq/pull/12389}{\#12389}%
\begin{footnote}[355]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12389}
%
\end{footnote}, by Martin Bodin, review of Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} The option \sphinxcode{\sphinxupquote{\sphinxhyphen{}I}} of coqchk was removed (it was
deprecated in Coq 8.8) (\sphinxhref{https://github.com/coq/coq/pull/12613}{\#12613}%
\begin{footnote}[356]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12613}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
\sphinxcode{\sphinxupquote{coqchk}} no longer reports names from inner modules of opaque modules as
axioms (\sphinxhref{https://github.com/coq/coq/pull/12862}{\#12862}%
\begin{footnote}[357]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12862}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/12845}{\#12845}%
\begin{footnote}[358]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12845}
%
\end{footnote}, by Jason Gross).

\end{itemize}


\subparagraph{CoqIDE}
\label{\detokenize{changes:id314}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Support showing diffs for {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Proof}}}}} in CoqIDE from the \sphinxcode{\sphinxupquote{\DUrole{notation}{View}}} menu.
See {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:id5}]{\sphinxcrossref{\DUrole{std,std-ref}{"Show Proof" differences}}}}.
(\sphinxhref{https://github.com/coq/coq/pull/12874}{\#12874}%
\begin{footnote}[359]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12874}
%
\end{footnote},
by Jim Fehrle and Enrico Tassi)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Support for flag {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:flag.Printing-Goal-Names}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Goal Names}}}}} in View menu
(\sphinxhref{https://github.com/coq/coq/pull/13145}{\#13145}%
\begin{footnote}[360]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13145}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Standard library}
\label{\detokenize{changes:id317}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
In the reals theory changed the epsilon in the definition of the modulus of convergence for CReal from 1/n (n in positive) to 2\textasciicircum{}z (z in Z)
so that a precision coarser than one is possible. Also added an upper bound to CReal to enable more efficient computations.
(\sphinxhref{https://github.com/coq/coq/pull/12186}{\#12186}%
\begin{footnote}[361]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12186}
%
\end{footnote},
by Michael Soegtrop).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Int63 notations now match up with the rest of the standard library: \sphinxcode{\sphinxupquote{\DUrole{name}{a} \DUrole{name,builtin,pseudo}{\textbackslash{}}\DUrole{operator}{\%}
\DUrole{name}{m}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{==} \DUrole{name}{n}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{<} \DUrole{name}{n}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{<=} \DUrole{name}{n}}}, and \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{≤} \DUrole{name}{n}}} have been replaced
with \sphinxcode{\sphinxupquote{\DUrole{name}{a} \DUrole{name}{mod} \DUrole{name}{m}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{=?} \DUrole{name}{n}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{<?} \DUrole{name}{n}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{<=?} \DUrole{name}{n}}}, and \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{≤?} \DUrole{name}{n}}}.
The old notations are still available as deprecated notations.  Additionally,
there is now a \sphinxcode{\sphinxupquote{Coq.Numbers.Cyclic.Int63.Int63.Int63Notations}} module that
users can import to get the \sphinxcode{\sphinxupquote{Int63}} notations without unqualifying the
various primitives (\sphinxhref{https://github.com/coq/coq/pull/12479}{\#12479}%
\begin{footnote}[362]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12479}
%
\end{footnote}, fixes
\sphinxhref{https://github.com/coq/coq/issues/12454}{\#12454}%
\begin{footnote}[363]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12454}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
PrimFloat notations now match up with the rest of the standard library: \sphinxcode{\sphinxupquote{\DUrole{name}{m}
\DUrole{operator}{==} \DUrole{name}{n}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{<} \DUrole{name}{n}}}, and \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{<=} \DUrole{name}{n}}} have been replaced with \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{=?} \DUrole{name}{n}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{m}
\DUrole{operator}{<?} \DUrole{name}{n}}}, and \sphinxcode{\sphinxupquote{\DUrole{name}{m} \DUrole{operator}{<=?} \DUrole{name}{n}}}.  The old notations are still available as deprecated
notations.  Additionally, there is now a
\sphinxcode{\sphinxupquote{Coq.Floats.PrimFloat.PrimFloatNotations}} module that users can import to
get the \sphinxcode{\sphinxupquote{PrimFloat}} notations without unqualifying the various primitives
(\sphinxhref{https://github.com/coq/coq/pull/12556}{\#12556}%
\begin{footnote}[364]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12556}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/12454}{\#12454}%
\begin{footnote}[365]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12454}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} the sort of cyclic numbers from Type to Set.
For backward compatibility, a dynamic sort was defined in the 3 packages bignums, coqprime and color.
See for example commit 6f62bda in bignums.
(\sphinxhref{https://github.com/coq/coq/pull/12801}{\#12801}%
\begin{footnote}[366]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12801}
%
\end{footnote},
by Vincent Semeria).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
\sphinxcode{\sphinxupquote{Require Import Coq.nsatz.NsatzTactic}} now allows using {\hyperref[\detokenize{addendum/nsatz:coq:tacn.nsatz}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nsatz}}}}}
with \sphinxcode{\sphinxupquote{Z}} and \sphinxcode{\sphinxupquote{Q}} without having to supply instances or using \sphinxcode{\sphinxupquote{Require Import Coq.nsatz.Nsatz}}, which
transitively requires unneeded files declaring axioms used in the reals
(\sphinxhref{https://github.com/coq/coq/pull/12861}{\#12861}%
\begin{footnote}[367]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12861}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12860}{\#12860}%
\begin{footnote}[368]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12860}
%
\end{footnote},
by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
\sphinxcode{\sphinxupquote{prod\_curry}} and \sphinxcode{\sphinxupquote{prod\_uncurry}}, in favor of \sphinxcode{\sphinxupquote{uncurry}} and \sphinxcode{\sphinxupquote{curry}}
(\sphinxhref{https://github.com/coq/coq/pull/12716}{\#12716}%
\begin{footnote}[369]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12716}
%
\end{footnote},
by Yishuai Li).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
New lemmas about \sphinxcode{\sphinxupquote{repeat}} in \sphinxcode{\sphinxupquote{List}} and \sphinxcode{\sphinxupquote{Permutation}}: \sphinxcode{\sphinxupquote{repeat\_app}}, \sphinxcode{\sphinxupquote{repeat\_eq\_app}}, \sphinxcode{\sphinxupquote{repeat\_eq\_cons}}, \sphinxcode{\sphinxupquote{repeat\_eq\_elt}}, \sphinxcode{\sphinxupquote{Forall\_eq\_repeat}}, \sphinxcode{\sphinxupquote{Permutation\_repeat}}
(\sphinxhref{https://github.com/coq/coq/pull/12799}{\#12799}%
\begin{footnote}[370]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12799}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Extend some list lemmas to both directions: \sphinxcode{\sphinxupquote{app\_inj\_tail\_iff}}, \sphinxcode{\sphinxupquote{app\_inv\_head\_iff}}, \sphinxcode{\sphinxupquote{app\_inv\_tail\_iff}}.
(\sphinxhref{https://github.com/coq/coq/pull/12094}{\#12094}%
\begin{footnote}[371]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12094}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12093}{\#12093}%
\begin{footnote}[372]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12093}
%
\end{footnote},
by Edward Wang).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{Decidable}} instance for negation
(\sphinxhref{https://github.com/coq/coq/pull/12420}{\#12420}%
\begin{footnote}[373]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12420}
%
\end{footnote},
by Yishuai Li).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
\sphinxcode{\sphinxupquote{Coq.Program.Wf.Fix\_F\_inv}} and \sphinxcode{\sphinxupquote{Coq.Program.Wf.Fix\_eq}} are now axiom\sphinxhyphen{}free. They no longer assume proof irrelevance.
(\sphinxhref{https://github.com/coq/coq/pull/13365}{\#13365}%
\begin{footnote}[374]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13365}
%
\end{footnote},
by Li\sphinxhyphen{}yao Xia).

\end{itemize}


\subparagraph{Infrastructure and dependencies}
\label{\detokenize{changes:id332}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
When compiled with OCaml >= 4.10.0, Coq will use the new best\sphinxhyphen{}fit GC
policy, which should provide some performance benefits. Coq's policy
is optimized for speed, but could increase memory consumption in
some cases. You are welcome to tune it using the \sphinxcode{\sphinxupquote{OCAMLRUNPARAM}}
variable and report back on good settings so we can improve the defaults.
(\sphinxhref{https://github.com/coq/coq/pull/13040}{\#13040}%
\begin{footnote}[375]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13040}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11277}{\#11277}%
\begin{footnote}[376]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11277}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Coq now uses the \sphinxhref{https://github.com/ocaml/Zarith}{zarith}%
\begin{footnote}[377]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/ocaml/Zarith}
%
\end{footnote}
library, based on GNU's gmp instead of \sphinxcode{\sphinxupquote{num}} which is
deprecated upstream. The custom \sphinxcode{\sphinxupquote{bigint}} module is
no longer provided.
(\sphinxhref{https://github.com/coq/coq/pull/11742}{\#11742}%
\begin{footnote}[378]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11742}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/13007}{\#13007}%
\begin{footnote}[379]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13007}
%
\end{footnote},
by Emilio Jesus Gallego Arias and Vicent Laporte, with help from
Frédéric Besson).

\end{itemize}


\paragraph{Changes in 8.13.0}
\label{\detokenize{changes:changes-in-8-13-0}}

\subparagraph{Commands and options}
\label{\detokenize{changes:id337}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The warning \sphinxcode{\sphinxupquote{custom\sphinxhyphen{}entry\sphinxhyphen{}overriden}} has been renamed to \sphinxcode{\sphinxupquote{custom\sphinxhyphen{}entry\sphinxhyphen{}overridden}} (with two d's).
(\sphinxhref{https://github.com/coq/coq/pull/13556}{\#13556}%
\begin{footnote}[380]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13556}
%
\end{footnote},
by Simon Friis Vindum).

\end{itemize}


\paragraph{Changes in 8.13.1}
\label{\detokenize{changes:changes-in-8-13-1}}

\subparagraph{Kernel}
\label{\detokenize{changes:id339}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Fix arities of VM opcodes for some floating\sphinxhyphen{}point operations
that could cause memory corruption
(\sphinxhref{https://github.com/coq/coq/pull/13867}{\#13867}%
\begin{footnote}[381]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13867}
%
\end{footnote},
by Guillaume Melquiond).

\end{itemize}


\subparagraph{CoqIDE}
\label{\detokenize{changes:id341}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Option \sphinxcode{\sphinxupquote{\sphinxhyphen{}v}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}version}} to CoqIDE
(\sphinxhref{https://github.com/coq/coq/pull/13870}{\#13870}%
\begin{footnote}[382]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13870}
%
\end{footnote},
by Guillaume Melquiond).

\end{itemize}


\paragraph{Changes in 8.13.2}
\label{\detokenize{changes:changes-in-8-13-2}}

\subparagraph{Kernel}
\label{\detokenize{changes:id343}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Crash when using {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}} on an irreducible \sphinxcode{\sphinxupquote{PArray.set}}
(\sphinxhref{https://github.com/coq/coq/pull/14005}{\#14005}%
\begin{footnote}[383]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14005}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13998}{\#13998}%
\begin{footnote}[384]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13998}
%
\end{footnote},
by Guillaume Melquiond).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Never store persistent arrays as VM / native structured values.
This could be used to make vo marshalling crash, and probably
breaking some other invariants of the kernel
(\sphinxhref{https://github.com/coq/coq/pull/14007}{\#14007}%
\begin{footnote}[385]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14007}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/14006}{\#14006}%
\begin{footnote}[386]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14006}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}


\subparagraph{Tactic language}
\label{\detokenize{changes:id348}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Ltac2 \sphinxcode{\sphinxupquote{Array.init}} no longer incurs exponential overhead when used
recursively (\sphinxhref{https://github.com/coq/coq/pull/14012}{\#14012}%
\begin{footnote}[387]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/14012}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/14011}{\#14011}%
\begin{footnote}[388]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/14011}
%
\end{footnote}, by Jason Gross).

\end{itemize}


\subsubsection{Version 8.12}
\label{\detokenize{changes:version-8-12}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id351}}
\sphinxAtStartPar
Coq version 8.12 integrates many usability improvements,
in particular with respect to notations, scopes and implicit arguments,
along with many bug fixes and major improvements to the reference manual.
The main changes include:
\begin{itemize}
\item {} 
\sphinxAtStartPar
New {\hyperref[\detokenize{changes:implicit}]{\sphinxcrossref{\DUrole{std,std-ref}{binder notation}}}} for non\sphinxhyphen{}maximal implicit arguments using \sphinxcode{\sphinxupquote{\DUrole{operator}{{[}} \DUrole{operator}{{]}}}}
allowing to set and see the implicit status of arguments immediately.

\item {} 
\sphinxAtStartPar
New notation \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Inductive} \DUrole{name}{I} \DUrole{name}{A} \DUrole{operator}{|} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{s} \DUrole{operator}{:=} \DUrole{operator}{...}}} to distinguish the
{\hyperref[\detokenize{changes:uniform}]{\sphinxcrossref{\DUrole{std,std-ref}{uniform}}}} from the non\sphinxhyphen{}uniform parameters in inductive definitions.

\item {} 
\sphinxAtStartPar
More robust and expressive treatment of {\hyperref[\detokenize{changes:implicitinductive}]{\sphinxcrossref{\DUrole{std,std-ref}{implicit inductive}}}}
parameters in inductive declarations.

\item {} 
\sphinxAtStartPar
Improvements in the treatment of implicit arguments and partially applied
constants in {\hyperref[\detokenize{changes:id381}]{\sphinxcrossref{\DUrole{std,std-ref}{notations}}}}, parsing of hexadecimal number notation and better
handling of scopes and coercions for printing.

\item {} 
\sphinxAtStartPar
A correct and efficient {\hyperref[\detokenize{changes:coercions}]{\sphinxcrossref{\DUrole{std,std-ref}{coercion coherence}}}} checking algorithm, avoiding
spurious or duplicate warnings.

\item {} 
\sphinxAtStartPar
An improved {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} {\hyperref[\detokenize{changes:search}]{\sphinxcrossref{\DUrole{std,std-ref}{command}}}} which accepts complex queries. Note that
this takes precedence over the now deprecated {\hyperref[\detokenize{changes:ssrsearch}]{\sphinxcrossref{\DUrole{std,std-ref}{ssreflect search}}}}.

\item {} 
\sphinxAtStartPar
Many additions and improvements of the {\hyperref[\detokenize{changes:id521}]{\sphinxcrossref{\DUrole{std,std-ref}{standard library}}}}.

\item {} 
\sphinxAtStartPar
Improvements to the {\hyperref[\detokenize{changes:refman}]{\sphinxcrossref{\DUrole{std,std-ref}{reference manual}}}} include a more logical organization
of chapters along with updated syntax descriptions that match Coq's grammar
in most but not all chapters.

\end{itemize}

\sphinxAtStartPar
Additionally, the \sphinxcode{\sphinxupquote{omega}} tactic is deprecated in this version of Coq,
and we recommend users to switch to {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} in new proof scripts.

\sphinxAtStartPar
See the {\hyperref[\detokenize{changes:changes-in-8-12-beta1}]{\sphinxcrossref{Changes in 8.12+beta1}}} section and following sections for the
detailed list of changes, including potentially breaking changes marked
with \sphinxstylestrong{Changed}.

\sphinxAtStartPar
Coq's documentation is available at \sphinxurl{https://coq.github.io/doc/v8.12/refman} (reference
manual), and \sphinxurl{https://coq.github.io/doc/v8.12/stdlib} (documentation of
the standard library). Developer documentation of the ML API is available
at \sphinxurl{https://coq.github.io/doc/v8.12/api}.

\sphinxAtStartPar
Maxime Dénès, Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop and Théo Zimmermann worked on maintaining and improving the
continuous integration system and package building infrastructure.

\sphinxAtStartPar
Erik Martin\sphinxhyphen{}Dorel has maintained the \sphinxhref{https://hub.docker.com/r/coqorg/coq}{Coq Docker images}%
\begin{footnote}[389]\sphinxAtStartFootnote
\sphinxnolinkurl{https://hub.docker.com/r/coqorg/coq}
%
\end{footnote} that are used in many Coq
projects for continuous integration.

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

\sphinxAtStartPar
Previously, most components of Coq had a single principal maintainer.
This was changed in 8.12 (\sphinxhref{https://github.com/coq/coq/pull/11295}{\#11295}%
\begin{footnote}[390]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11295}
%
\end{footnote}) so that every component now has
a team of maintainers, who are in charge of reviewing and
merging incoming pull requests.  This gave us a chance to
significantly expand the pool of maintainters and provide faster
feedback to contributors.  Special thanks to all our maintainers!

\sphinxAtStartPar
Our current 31 maintainers are Yves Bertot, Frédéric Besson, Tej
Chajed, Cyril Cohen, Pierre Corbineau, Pierre Courtieu, Maxime Dénès,
Jim Fehrle, Julien Forest, Emilio Jesús Gallego Arias, Gaëtan Gilbert,
Georges Gonthier, Benjamin Grégoire, Jason Gross, Hugo Herbelin,
Vincent Laporte, Assia Mahboubi, Kenji Maillard, Guillaume Melquiond,
Pierre\sphinxhyphen{}Marie Pédrot, Clément Pit\sphinxhyphen{}Claudel, Kazuhiko Sakaguchi, Vincent
Semeria, Michael Soegtrop, Arnaud Spiwack, Matthieu Sozeau, Enrico
Tassi, Laurent Théry, Anton Trunov, Li\sphinxhyphen{}yao Xia, Théo Zimmermann

\sphinxAtStartPar
The 59 contributors to this version are Abhishek Anand, Yves Bertot, Frédéric
Besson, Lasse Blaauwbroek, Simon Boulier, Quentin Carbonneaux, Tej Chajed,
Arthur Charguéraud, Cyril Cohen, Pierre Courtieu, Matthew Dempsky, Maxime Dénès,
Andres Erbsen, Erika (@rrika), Nikita Eshkeev, Jim Fehrle, @formalize, Emilio
Jesús Gallego Arias, Paolo G. Giarrusso, Gaëtan Gilbert, Jason Gross, Samuel
Gruetter, Attila Gáspár, Hugo Herbelin, Jan\sphinxhyphen{}Oliver Kaiser, Robbert Krebbers,
Vincent Laporte, Olivier Laurent, Xavier Leroy, Thomas Letan, Yishuai Li,
Kenji Maillard, Erik Martin\sphinxhyphen{}Dorel, Guillaume Melquiond, Ike Mulder,
Guillaume Munch\sphinxhyphen{}Maccagnoni, Antonio Nikishaev, Karl Palmskog, Pierre\sphinxhyphen{}Marie
Pédrot, Clément Pit\sphinxhyphen{}Claudel, Ramkumar Ramachandra, Lars Rasmusson, Daniel
de Rauglaudre, Talia Ringer, Pierre Roux, Kazuhiko Sakaguchi, Vincent Semeria,
@scinart, Kartik Singhal, Michael Soegtrop, Matthieu Sozeau, Enrico Tassi,
Laurent Théry, Ralf Treinen, Anton Trunov, Bernhard M. Wiedemann, Li\sphinxhyphen{}yao Xia,
Nickolai Zeldovich and Théo Zimmermann.

\sphinxAtStartPar
Many power users helped to improve the design of this new version via
the GitHub issue and pull request system, the Coq development mailing list
\sphinxhref{mailto:coqdev@inria.fr}{coqdev@inria.fr}, the \sphinxhref{mailto:coq-club@inria.fr}{coq\sphinxhyphen{}club@inria.fr} mailing list, the \sphinxhref{https://coq.discourse.group/}{Discourse forum}%
\begin{footnote}[391]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.discourse.group/}
%
\end{footnote} and the new \sphinxhref{http://coq.zulipchat.com}{Coq Zulip chat}%
\begin{footnote}[392]\sphinxAtStartFootnote
\sphinxnolinkurl{http://coq.zulipchat.com}
%
\end{footnote}
(thanks to Cyril Cohen for organizing the move from Gitter).

\sphinxAtStartPar
Version 8.12's development spanned 6 months from the release of
Coq 8.11.0. Emilio Jesus Gallego Arias and Théo Zimmermann are
the release managers of Coq 8.12. This release is the result of
\textasciitilde{}500 PRs merged, closing \textasciitilde{}100 issues.

\begin{DUlineblock}{0em}
\item[] Nantes, June 2020,
\item[] Matthieu Sozeau for the Coq development team
\item[] 
\end{DUlineblock}


\paragraph{Changes in 8.12+beta1}
\label{\detokenize{changes:changes-in-8-12-beta1}}
\begin{sphinxShadowBox}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id979}}{\hyperref[\detokenize{changes:id357}]{\sphinxcrossref{Kernel}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id980}}{\hyperref[\detokenize{changes:id360}]{\sphinxcrossref{Specification language, type inference}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id981}}{\hyperref[\detokenize{changes:id381}]{\sphinxcrossref{Notations}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id982}}{\hyperref[\detokenize{changes:id402}]{\sphinxcrossref{Tactics}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id983}}{\hyperref[\detokenize{changes:id443}]{\sphinxcrossref{Tactic language}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id984}}{\hyperref[\detokenize{changes:id452}]{\sphinxcrossref{SSReflect}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id985}}{\hyperref[\detokenize{changes:flags-options-and-attributes}]{\sphinxcrossref{Flags, options and attributes}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id986}}{\hyperref[\detokenize{changes:commands}]{\sphinxcrossref{Commands}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id987}}{\hyperref[\detokenize{changes:id483}]{\sphinxcrossref{Tools}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id988}}{\hyperref[\detokenize{changes:id518}]{\sphinxcrossref{CoqIDE}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id989}}{\hyperref[\detokenize{changes:id521}]{\sphinxcrossref{Standard library}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id990}}{\hyperref[\detokenize{changes:reals-library}]{\sphinxcrossref{Reals library}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id991}}{\hyperref[\detokenize{changes:extraction}]{\sphinxcrossref{Extraction}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id992}}{\hyperref[\detokenize{changes:refman}]{\sphinxcrossref{Reference manual}}}

\item {} 
\sphinxAtStartPar
\phantomsection\label{\detokenize{changes:id993}}{\hyperref[\detokenize{changes:id595}]{\sphinxcrossref{Infrastructure and dependencies}}}

\end{itemize}
\end{sphinxShadowBox}


\subparagraph{Kernel}
\label{\detokenize{changes:id357}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Specification of \sphinxcode{\sphinxupquote{\DUrole{notation}{PrimFloat.leb}}} which made
\sphinxcode{\sphinxupquote{\DUrole{notation}{(x <= y)\%float}}} true for any non NaN \sphinxcode{\sphinxupquote{\DUrole{notation}{x}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{y}}}.
(\sphinxhref{https://github.com/coq/coq/pull/12484}{\#12484}%
\begin{footnote}[393]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12484}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12483}{\#12483}%
\begin{footnote}[394]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12483}
%
\end{footnote},
by Pierre Roux).

\end{itemize}


\subparagraph{Specification language, type inference}
\label{\detokenize{changes:id360}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The deprecation warning raised since Coq 8.10 when a trailing
implicit is declared to be non\sphinxhyphen{}maximally inserted (with the command
{\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}}) has been turned into an error
(\sphinxhref{https://github.com/coq/coq/pull/11368}{\#11368}%
\begin{footnote}[395]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11368}
%
\end{footnote},
by SimonBoulier).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Typeclass resolution, accessible through {\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}},
now suspends constraints according to their modes
instead of failing. If a typeclass constraint does not match
any of the declared modes for its class, the constraint is postponed, and
the proof search continues on other goals. Proof search does a fixed point
computation to try to solve them at a later stage of resolution. It does
not fail if there remain only stuck constraints at the end of resolution.
This makes typeclasses with declared modes more robust with respect to the
order of resolution.
(\sphinxhref{https://github.com/coq/coq/pull/10858}{\#10858}%
\begin{footnote}[396]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10858}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9058}{\#9058}%
\begin{footnote}[397]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9058}
%
\end{footnote}, by Matthieu Sozeau).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Warn when manual implicit arguments are used in unexpected positions
of a term (e.g. in \sphinxcode{\sphinxupquote{Check id (forall \{x\}, x)}}) or when an implicit
argument name is shadowed (e.g. in \sphinxcode{\sphinxupquote{Check fun f : forall \{x:nat\}
\{x\}, nat => f}})
(\sphinxhref{https://github.com/coq/coq/pull/10202}{\#10202}%
\begin{footnote}[398]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10202}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} now supports setting
implicit an anonymous argument, as e.g. in \sphinxcode{\sphinxupquote{Arguments id \{A\} \{\_\}}}
(\sphinxhref{https://github.com/coq/coq/pull/11098}{\#11098}%
\begin{footnote}[399]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11098}
%
\end{footnote},
by Hugo Herbelin, fixes \sphinxhref{https://github.com/coq/coq/pull/4696}{\#4696}%
\begin{footnote}[400]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/4696}
%
\end{footnote}, \sphinxhref{https://github.com/coq/coq/pull/5173}{\#5173}%
\begin{footnote}[401]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/5173}
%
\end{footnote}, \sphinxhref{https://github.com/coq/coq/pull/9098}{\#9098}%
\begin{footnote}[402]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9098}
%
\end{footnote}).

\phantomsection\label{\detokenize{changes:implicit}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Syntax for non\sphinxhyphen{}maximal implicit arguments in definitions and terms using
square brackets. The syntax is \sphinxcode{\sphinxupquote{{[}x : A{]}}}, \sphinxcode{\sphinxupquote{{[}x{]}}}, \sphinxcode{\sphinxupquote{`{[}A{]}}}
to be consistent with the command {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/11235}{\#11235}%
\begin{footnote}[403]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11235}
%
\end{footnote},
by Simon Boulier).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{language/extensions/implicit-arguments:coq:cmd.Implicit-Types}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Implicit Types}}}}} are now taken into account for printing. To inhibit it,
unset the {\hyperref[\detokenize{language/extensions/implicit-arguments:coq:flag.Printing-Use-Implicit-Types}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Use Implicit Types}}}}} flag
(\sphinxhref{https://github.com/coq/coq/pull/11261}{\#11261}%
\begin{footnote}[404]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11261}
%
\end{footnote},
by Hugo Herbelin, granting \sphinxhref{https://github.com/coq/coq/pull/10366}{\#10366}%
\begin{footnote}[405]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10366}
%
\end{footnote}).

\phantomsection\label{\detokenize{changes:uniform}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
New syntax {\hyperref[\detokenize{language/core/inductive:coq:cmd.Inductive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Inductive}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} | \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}} := ...}}}
to specify which parameters of an inductive type are uniform.
See {\hyperref[\detokenize{language/core/inductive:parametrized-inductive-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Parameterized inductive types}}}}
(\sphinxhref{https://github.com/coq/coq/pull/11600}{\#11600}%
\begin{footnote}[406]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11600}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Warn when using {\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} or {\hyperref[\detokenize{language/core/coinductive:coq:cmd.CoFixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}} for
definitions which are not recursive
(\sphinxhref{https://github.com/coq/coq/pull/12121}{\#12121}%
\begin{footnote}[407]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12121}
%
\end{footnote},
by Hugo Herbelin).

\phantomsection\label{\detokenize{changes:implicitinductive}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
More robust and expressive treatment of implicit inductive
parameters in inductive declarations (\sphinxhref{https://github.com/coq/coq/pull/11579}{\#11579}%
\begin{footnote}[408]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11579}
%
\end{footnote}, by Maxime Dénès, Gaëtan
Gilbert and Jasper Hugunin; fixes \sphinxhref{https://github.com/coq/coq/pull/7253}{\#7253}%
\begin{footnote}[409]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7253}
%
\end{footnote} and \sphinxhref{https://github.com/coq/coq/pull/11585}{\#11585}%
\begin{footnote}[410]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11585}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Anomaly which could be raised when printing binders with implicit types
(\sphinxhref{https://github.com/coq/coq/pull/12323}{\#12323}%
\begin{footnote}[411]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12323}
%
\end{footnote},
by Hugo Herbelin; fixes \sphinxhref{https://github.com/coq/coq/pull/12322}{\#12322}%
\begin{footnote}[412]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12322}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Case of an anomaly in trying to infer the return clause of an ill\sphinxhyphen{}typed \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}}
(\sphinxhref{https://github.com/coq/coq/pull/12422}{\#12422}%
\begin{footnote}[413]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12422}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/pull/12418}{\#12418}%
\begin{footnote}[414]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12418}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subparagraph{Notations}
\label{\detokenize{changes:id381}}\label{\detokenize{changes:id382}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} Notation scopes are now always inherited in
notations binding a partially applied constant, including for
notations binding an expression of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{@{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}. The latter was
not the case beforehand
(part of \sphinxhref{https://github.com/coq/coq/pull/11120}{\#11120}%
\begin{footnote}[415]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11120}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The printing algorithm now interleaves search for notations and removal of coercions
(\sphinxhref{https://github.com/coq/coq/pull/11172}{\#11172}%
\begin{footnote}[416]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11172}
%
\end{footnote}, by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Nicer printing for decimal constants in R and Q.
1.5 is now printed 1.5 rather than 15e\sphinxhyphen{}1
(\sphinxhref{https://github.com/coq/coq/pull/11848}{\#11848}%
\begin{footnote}[417]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11848}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} deprecated \sphinxcode{\sphinxupquote{compat}} modifier of {\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}}}}} commands. Use the {\hyperref[\detokenize{using/libraries/writing:coq:attr.deprecated}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{deprecated}}}}} attribute instead
(\sphinxhref{https://github.com/coq/coq/pull/11113}{\#11113}%
\begin{footnote}[418]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11113}
%
\end{footnote},
by Théo Zimmermann, with help from Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
Numeral Notation on \sphinxcode{\sphinxupquote{Decimal.uint}}, \sphinxcode{\sphinxupquote{Decimal.int}} and
\sphinxcode{\sphinxupquote{Decimal.decimal}} are replaced respectively by numeral notations
on \sphinxcode{\sphinxupquote{Numeral.uint}}, \sphinxcode{\sphinxupquote{Numeral.int}} and \sphinxcode{\sphinxupquote{Numeral.numeral}}
(\sphinxhref{https://github.com/coq/coq/pull/11948}{\#11948}%
\begin{footnote}[419]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11948}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Notations declared with the \sphinxcode{\sphinxupquote{where}} clause in the declaration of
inductive types, coinductive types, record fields, fixpoints and
cofixpoints now support the \sphinxcode{\sphinxupquote{only parsing}} modifier
(\sphinxhref{https://github.com/coq/coq/pull/11602}{\#11602}%
\begin{footnote}[420]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11602}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:flag.Printing-Parentheses}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Parentheses}}}}} flag to print parentheses even when
implied by associativity or precedence
(\sphinxhref{https://github.com/coq/coq/pull/11650}{\#11650}%
\begin{footnote}[421]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11650}
%
\end{footnote},
by Hugo Herbelin and Abhishek Anand).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Numeral notations now parse hexadecimal constants such as \sphinxcode{\sphinxupquote{0x2a}}
or \sphinxcode{\sphinxupquote{0xb.2ap\sphinxhyphen{}2}}. Parsers added for \sphinxcode{\sphinxupquote{\DUrole{name}{nat}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{positive}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{N}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{Q}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{R}}}, primitive integers and primitive floats
(\sphinxhref{https://github.com/coq/coq/pull/11948}{\#11948}%
\begin{footnote}[422]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11948}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Abbreviations support arguments occurring both in term and binder position
(\sphinxhref{https://github.com/coq/coq/pull/8808}{\#8808}%
\begin{footnote}[423]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8808}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Different interpretations in different scopes of the same notation
string can now be associated with different printing formats (\sphinxhref{https://github.com/coq/coq/pull/10832}{\#10832}%
\begin{footnote}[424]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10832}
%
\end{footnote}, by Hugo Herbelin,
fixes \sphinxhref{https://github.com/coq/coq/issues/6092}{\#6092}%
\begin{footnote}[425]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/6092}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/7766}{\#7766}%
\begin{footnote}[426]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7766}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} Parsing and printing consistently handle inheritance of implicit
arguments in notations. With the exception of notations of
the form \sphinxcode{\sphinxupquote{\DUrole{notation}{Notation {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} := @{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{Notation {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := @{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} which
inhibit implicit arguments, all notations binding a partially
applied constant, as e.g. in \sphinxcode{\sphinxupquote{\DUrole{notation}{Notation {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} := ({\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}\DUrole{notation-sup}{+}})}}},
or \sphinxcode{\sphinxupquote{\DUrole{notation}{Notation {\hyperref[\detokenize{language/core/basic:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}} := (@{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}\DUrole{notation-sup}{+}})}}}, or
\sphinxcode{\sphinxupquote{\DUrole{notation}{Notation {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := ({\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}\DUrole{notation-sup}{+}})}}}, or \sphinxcode{\sphinxupquote{\DUrole{notation}{Notation {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}
:= (@{\hyperref[\detokenize{language/core/modules:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/assumptions:grammar-token-arg}]{\sphinxcrossref{\DUrole{hole}{arg}}}}}\DUrole{notation-sup}{+}})}}}, inherit the remaining implicit arguments
(\sphinxhref{https://github.com/coq/coq/pull/11120}{\#11120}%
\begin{footnote}[427]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11120}
%
\end{footnote}, by Hugo
Herbelin, fixing \sphinxhref{https://github.com/coq/coq/pull/4690}{\#4690}%
\begin{footnote}[428]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/4690}
%
\end{footnote} and
\sphinxhref{https://github.com/coq/coq/pull/11091}{\#11091}%
\begin{footnote}[429]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11091}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Notations in \sphinxcode{\sphinxupquote{only printing}} mode do not uselessly reserve parsing keywords
(\sphinxhref{https://github.com/coq/coq/pull/11590}{\#11590}%
\begin{footnote}[430]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11590}
%
\end{footnote},
by Hugo Herbelin, fixes \sphinxhref{https://github.com/coq/coq/pull/9741}{\#9741}%
\begin{footnote}[431]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9741}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Numeral Notations now play better with multiple scopes for the same
inductive type. Previously, when multiple numeral notations were defined
for the same inductive, only the last one was considered for
printing. Now, among the notations that are usable for printing and either
have a scope delimiter or are open, the selection is made according
to the order of open scopes, or according to the last defined
notation if no appropriate scope is open
(\sphinxhref{https://github.com/coq/coq/pull/12163}{\#12163}%
\begin{footnote}[432]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12163}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/pull/12159}{\#12159}%
\begin{footnote}[433]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12159}
%
\end{footnote},
by Pierre Roux, review by Hugo Herbelin and Jason Gross).

\end{itemize}


\subparagraph{Tactics}
\label{\detokenize{changes:id402}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.rapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rapply}}}}} tactic in \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Program}\DUrole{operator}{.}\DUrole{name}{Tactics}}} now handles
arbitrary numbers of underscores and takes in a \sphinxcode{\sphinxupquote{\DUrole{name}{uconstr}}}.  In
rare cases where users were relying on {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.rapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rapply}}}}} inserting
exactly 15 underscores and no more, due to the lemma having a
completely unspecified codomain (and thus allowing for any number of
underscores), the tactic will now loop instead (\sphinxhref{https://github.com/coq/coq/pull/10760}{\#10760}%
\begin{footnote}[434]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10760}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The \sphinxcode{\sphinxupquote{\DUrole{keyword}{auto} \DUrole{keyword}{with} \DUrole{name}{zarith}}} tactic and variations (including
{\hyperref[\detokenize{proofs/automatic-tactics/logic:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}}) may now call {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} instead of \sphinxcode{\sphinxupquote{omega}}
(when the \sphinxcode{\sphinxupquote{Omega}} module is loaded); more goals may be automatically
solved, fewer section variables will be captured spuriously
(\sphinxhref{https://github.com/coq/coq/pull/11018}{\#11018}%
\begin{footnote}[435]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11018}
%
\end{footnote},
by Vincent Laporte).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The new {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:flag.NativeCompute-Timing}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{NativeCompute Timing}}}}} flag causes calls to
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}} (as well as kernel calls to the native
compiler) to emit separate timing information about conversion to
native code, compilation, execution, and reification.  It replaces
the timing information previously emitted when the \sphinxcode{\sphinxupquote{\sphinxhyphen{}debug}}
command\sphinxhyphen{}line flag was set, and allows more fine\sphinxhyphen{}grained timing of
the native compiler
(\sphinxhref{https://github.com/coq/coq/pull/11025}{\#11025}%
\begin{footnote}[436]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11025}
%
\end{footnote}, by Jason Gross).
Additionally, the timing information now uses real time rather than
user time (fixes \sphinxhref{https://github.com/coq/coq/issues/11962}{\#11962}%
\begin{footnote}[437]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11962}
%
\end{footnote}, \sphinxhref{https://github.com/coq/coq/pull/11963}{\#11963}%
\begin{footnote}[438]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11963}
%
\end{footnote}, by Jason Gross)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Improve the efficiency of \sphinxcode{\sphinxupquote{PreOmega.elim\_let}} using an iterator implemented in OCaml
(\sphinxhref{https://github.com/coq/coq/pull/11370}{\#11370}%
\begin{footnote}[439]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11370}
%
\end{footnote}, by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Improve the efficiency of {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} by rewritting the remaining Ltac code in OCaml
(\sphinxhref{https://github.com/coq/coq/pull/11429}{\#11429}%
\begin{footnote}[440]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11429}
%
\end{footnote}, by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Backtrace information for tactics has been improved
(\sphinxhref{https://github.com/coq/coq/pull/11755}{\#11755}%
\begin{footnote}[441]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11755}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The default tactic used by \sphinxcode{\sphinxupquote{\DUrole{name}{firstorder}}} is
\sphinxcode{\sphinxupquote{\DUrole{keyword}{auto} \DUrole{keyword}{with} \DUrole{name}{core}}} instead of \sphinxcode{\sphinxupquote{\DUrole{keyword}{auto} \DUrole{keyword}{with} \DUrole{operator}{*}}};
see {\hyperref[\detokenize{proofs/automatic-tactics/logic:decisionprocedures}]{\sphinxcrossref{\DUrole{std,std-ref}{Solvers for logic and equality}}}} for details;
old behavior can be reset by using the \sphinxcode{\sphinxupquote{\sphinxhyphen{}compat 8.12}} command\sphinxhyphen{}line flag;
to ease the migration of legacy code, the default solver can be set to \sphinxcode{\sphinxupquote{debug auto with *}}
with \sphinxcode{\sphinxupquote{Set Firstorder Solver debug auto with *}}
(\sphinxhref{https://github.com/coq/coq/pull/11760}{\#11760}%
\begin{footnote}[442]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11760}
%
\end{footnote},
by Vincent Laporte).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
{\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.autounfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autounfold}}}}} no longer fails when the {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}
command is used on constants in the hint databases
(\sphinxhref{https://github.com/coq/coq/pull/11883}{\#11883}%
\begin{footnote}[443]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11883}
%
\end{footnote},
by Attila Gáspár).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Tactics with qualified name of the form \sphinxcode{\sphinxupquote{Coq.Init.Notations}} are
now qualified with prefix \sphinxcode{\sphinxupquote{Coq.Init.Ltac}}; users of the \sphinxcode{\sphinxupquote{\sphinxhyphen{}noinit}}
option should now import \sphinxcode{\sphinxupquote{Coq.Init.Ltac}} if they want to use Ltac
(\sphinxhref{https://github.com/coq/coq/pull/12023}{\#12023}%
\begin{footnote}[444]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12023}
%
\end{footnote},
by Hugo Herbelin; minor source of incompatibilities).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Tactic {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} now fails over a section variable which is
indirectly dependent in the goal; the incompatibility can generally
be fixed by first clearing the hypotheses causing an indirect
dependency, as reported by the error message, or by using {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{... in *}}}
instead; similarly, {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}} has no more effect on such variables
(\sphinxhref{https://github.com/coq/coq/pull/12146}{\#12146}%
\begin{footnote}[445]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12146}
%
\end{footnote},
by Hugo Herbelin; fixes \sphinxhref{https://github.com/coq/coq/pull/10812}{\#10812}%
\begin{footnote}[446]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10812}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/pull/12139}{\#12139}%
\begin{footnote}[447]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12139}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The check that {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}} arguments were indeed unfoldable has been moved to runtime
(\sphinxhref{https://github.com/coq/coq/pull/12256}{\#12256}%
\begin{footnote}[448]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12256}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot; fixes
\sphinxhref{https://github.com/coq/coq/issues/5764}{\#5764}%
\begin{footnote}[449]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/5764}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/issues/5159}{\#5159}%
\begin{footnote}[450]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/5159}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/issues/4925}{\#4925}%
\begin{footnote}[451]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4925}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/11727}{\#11727}%
\begin{footnote}[452]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11727}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed}
When the tactic {\hyperref[\detokenize{using/libraries/funind:coq:tacn.functional-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional induction}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{1}}$ c$_{\text{2}}$ ... c$_{\text{n}}$}}} is used
with no parenthesis around \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{1}}$ c$_{\text{2}}$ ... c$_{\text{n}}$}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{1}}$ c$_{\text{2}}$ ... c$_{\text{n}}$}}} is now
read as one single applicative term. In particular implicit
arguments should be omitted. Rare source of incompatibility
(\sphinxhref{https://github.com/coq/coq/pull/12326}{\#12326}%
\begin{footnote}[453]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12326}
%
\end{footnote},
by Pierre Courtieu).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
When using {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.exists}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exists}}}}} or {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.eexists}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eexists}}}}} with multiple arguments,
the evaluation of arguments and applications of constructors are now interleaved.
This improves unification in some cases
(\sphinxhref{https://github.com/coq/coq/pull/12366}{\#12366}%
\begin{footnote}[454]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12366}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12365}{\#12365}%
\begin{footnote}[455]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12365}
%
\end{footnote},
by Attila Gáspár).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Undocumented \sphinxcode{\sphinxupquote{omega with}}.  Using {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} is the recommended
replacement, although the old semantics of \sphinxcode{\sphinxupquote{omega with *}} can also
be recovered with \sphinxcode{\sphinxupquote{zify; omega}}
(\sphinxhref{https://github.com/coq/coq/pull/11288}{\#11288}%
\begin{footnote}[456]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11288}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Deprecated syntax \sphinxcode{\sphinxupquote{\_eqn}} for {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.remember}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{remember}}}}}.
Use \sphinxcode{\sphinxupquote{eqn:}} syntax instead
(\sphinxhref{https://github.com/coq/coq/pull/11877}{\#11877}%
\begin{footnote}[457]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11877}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
\sphinxcode{\sphinxupquote{at}} clauses can no longer be used with {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.autounfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autounfold}}}}}.
Since they had no effect, it is safe to remove them
(\sphinxhref{https://github.com/coq/coq/pull/11883}{\#11883}%
\begin{footnote}[458]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11883}
%
\end{footnote},
by Attila Gáspár).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
The \sphinxcode{\sphinxupquote{omega}} tactic is deprecated;
use {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} from the {\hyperref[\detokenize{addendum/micromega:micromega}]{\sphinxcrossref{\DUrole{std,std-ref}{Micromega}}}} plugin instead
(\sphinxhref{https://github.com/coq/coq/pull/11976}{\#11976}%
\begin{footnote}[459]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11976}
%
\end{footnote},
by Vincent Laporte).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} tactic is now aware of \sphinxcode{\sphinxupquote{Pos.pred\_double}}, \sphinxcode{\sphinxupquote{Pos.pred\_N}},
\sphinxcode{\sphinxupquote{Pos.of\_nat}}, \sphinxcode{\sphinxupquote{Pos.add\_carry}}, \sphinxcode{\sphinxupquote{Pos.pow}}, \sphinxcode{\sphinxupquote{Pos.square}}, \sphinxcode{\sphinxupquote{Z.pow}}, \sphinxcode{\sphinxupquote{Z.double}},
\sphinxcode{\sphinxupquote{Z.pred\_double}}, \sphinxcode{\sphinxupquote{Z.succ\_double}}, \sphinxcode{\sphinxupquote{Z.square}}, \sphinxcode{\sphinxupquote{Z.div2}}, and \sphinxcode{\sphinxupquote{Z.quot2}}.
Injections for internal definitions in module \sphinxcode{\sphinxupquote{ZifyBool}} (\sphinxcode{\sphinxupquote{isZero}} and \sphinxcode{\sphinxupquote{isLeZero}})
are also added to help users to declare new {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} class instances using
Micromega tactics
(\sphinxhref{https://github.com/coq/coq/pull/10998}{\#10998}%
\begin{footnote}[460]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10998}
%
\end{footnote}, by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{addendum/micromega:coq:cmd.Show-Lia-Profile}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Lia Profile}}}}} prints some statistics about {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} calls
(\sphinxhref{https://github.com/coq/coq/pull/11474}{\#11474}%
\begin{footnote}[461]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11474}
%
\end{footnote},  by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Syntax {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.pose-proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose proof}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:={\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} as an alternative to
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.pose-proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose proof}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, following the model of
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.pose}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:={\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}
(\sphinxhref{https://github.com/coq/coq/pull/11522}{\#11522}%
\begin{footnote}[462]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11522}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
New tactical {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.with_strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{with\_strategy}}}}} which behaves like the command
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:cmd.Strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Strategy}}}}}, with effects local to the given tactic
(\sphinxhref{https://github.com/coq/coq/pull/12129}{\#12129}%
\begin{footnote}[463]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12129}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} tactic is now aware of \sphinxcode{\sphinxupquote{Nat.le}}, \sphinxcode{\sphinxupquote{Nat.lt}} and \sphinxcode{\sphinxupquote{Nat.eq}}
(\sphinxhref{https://github.com/coq/coq/pull/12213}{\#12213}%
\begin{footnote}[464]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12213}
%
\end{footnote}, by Frédéric Besson;
fixes \sphinxhref{https://github.com/coq/coq/issues/12210}{\#12210}%
\begin{footnote}[465]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12210}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
{\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} now handles \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{pow\_pos}}} by default.
In Coq 8.11, this was the case only when loading module
\sphinxcode{\sphinxupquote{\DUrole{name}{ZifyPow}}} because this triggered a regression of {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}}.
The regression is now fixed, and the module kept only for compatibility
(\sphinxhref{https://github.com/coq/coq/pull/11362}{\#11362}%
\begin{footnote}[466]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11362}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11191}{\#11191}%
\begin{footnote}[467]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11191}
%
\end{footnote},
by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Efficiency regression of {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/11474}{\#11474}%
\begin{footnote}[468]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11474}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11436}{\#11436}%
\begin{footnote}[469]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11436}
%
\end{footnote},
by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
The behavior of {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.autounfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autounfold}}}}} no longer depends on the names of terms and modules
(\sphinxhref{https://github.com/coq/coq/pull/11883}{\#11883}%
\begin{footnote}[470]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11883}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/7812}{\#7812}%
\begin{footnote}[471]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7812}
%
\end{footnote},
by Attila Gáspár).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Wrong type error in tactic {\hyperref[\detokenize{using/libraries/funind:coq:tacn.functional-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional induction}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/12326}{\#12326}%
\begin{footnote}[472]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12326}
%
\end{footnote},
by Pierre Courtieu,
fixes \sphinxhref{https://github.com/coq/coq/issues/11761}{\#11761}%
\begin{footnote}[473]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11761}
%
\end{footnote},
reported by Lasse Blaauwbroek).

\end{itemize}


\subparagraph{Tactic language}
\label{\detokenize{changes:id443}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The "reference" tactic generic argument now accepts arbitrary
variables of the goal context
(\sphinxhref{https://github.com/coq/coq/pull/12254}{\#12254}%
\begin{footnote}[474]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12254}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
An array library for Ltac2 (as compatible as possible with OCaml standard library)
(\sphinxhref{https://github.com/coq/coq/pull/10343}{\#10343}%
\begin{footnote}[475]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10343}
%
\end{footnote},
by Michael Soegtrop).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The Ltac2 rebinding command {\hyperref[\detokenize{proof-engine/ltac2:coq:cmd.Ltac2-Set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac2 Set}}}}} has been extended with the ability to
give a name to the old value so as to be able to reuse it inside the
new one
(\sphinxhref{https://github.com/coq/coq/pull/11503}{\#11503}%
\begin{footnote}[476]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11503}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Ltac2 notations for {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.enough}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{enough}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eenough}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eenough}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/11740}{\#11740}%
\begin{footnote}[477]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11740}
%
\end{footnote},
by Michael Soegtrop).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
New Ltac2 function \sphinxcode{\sphinxupquote{Fresh.Free.of\_goal}} to return the list of
names of declarations of the current goal; new Ltac2 function
\sphinxcode{\sphinxupquote{Fresh.in\_goal}} to return a variable fresh in the current goal
(\sphinxhref{https://github.com/coq/coq/pull/11882}{\#11882}%
\begin{footnote}[478]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11882}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Ltac2 notations for reductions in terms: \sphinxcode{\sphinxupquote{\DUrole{notation}{eval {\hyperref[\detokenize{proofs/writing-proofs/equality:grammar-token-red_expr}]{\sphinxcrossref{\DUrole{hole}{red\_expr}}}} in {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/11981}{\#11981}%
\begin{footnote}[479]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11981}
%
\end{footnote},
by Michael Soegtrop).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
The {\hyperref[\detokenize{proof-engine/ltac:coq:flag.Ltac-Profiling}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac Profiling}}}}} machinery now correctly handles
backtracking into multi\sphinxhyphen{}success tactics.  The call\sphinxhyphen{}counts of some
tactics are unfortunately inflated by 1, as some tactics are
implicitly implemented as \sphinxcode{\sphinxupquote{\DUrole{name}{tac} \DUrole{operator}{+} \DUrole{name}{fail}}}, which has two
entry\sphinxhyphen{}points rather than one (fixes \sphinxhref{https://github.com/coq/coq/issues/12196}{\#12196}%
\begin{footnote}[480]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12196}
%
\end{footnote}, \sphinxhref{https://github.com/coq/coq/pull/12197}{\#12197}%
\begin{footnote}[481]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12197}
%
\end{footnote}, by Jason Gross).

\end{itemize}


\subparagraph{SSReflect}
\label{\detokenize{changes:id452}}\begin{quote}
\phantomsection\label{\detokenize{changes:ssrsearch}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:cmd.Search-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search (ssreflect)}}}}} command that used to be
available when loading the \sphinxcode{\sphinxupquote{ssreflect}} plugin has been moved to a
separate plugin that needs to be loaded separately: \sphinxcode{\sphinxupquote{ssrsearch}}
(part of \sphinxhref{https://github.com/coq/coq/pull/8855}{\#8855}%
\begin{footnote}[482]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8855}
%
\end{footnote}, fixes
\sphinxhref{https://github.com/coq/coq/issues/12253}{\#12253}%
\begin{footnote}[483]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12253}
%
\end{footnote}, by Théo
Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:cmd.Search-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search (ssreflect)}}}}} (available through
\sphinxcode{\sphinxupquote{Require ssrsearch.}}) in favor of the \sphinxcode{\sphinxupquote{headconcl:}} clause of
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} (part of \sphinxhref{https://github.com/coq/coq/pull/8855}{\#8855}%
\begin{footnote}[484]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8855}
%
\end{footnote}, by Théo Zimmermann).

\end{itemize}


\subparagraph{Flags, options and attributes}
\label{\detokenize{changes:flags-options-and-attributes}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{Legacy attributes}}}} can now be passed
in any order (\sphinxhref{https://github.com/coq/coq/pull/11665}{\#11665}%
\begin{footnote}[485]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11665}
%
\end{footnote}, by
Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} \sphinxcode{\sphinxupquote{Typeclasses Axioms Are Instances}} flag, deprecated since 8.10.
Use {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Declare-Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare Instance}}}}} for axioms which should be instances
(\sphinxhref{https://github.com/coq/coq/pull/11185}{\#11185}%
\begin{footnote}[486]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11185}
%
\end{footnote}, by Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} Deprecated unsound compatibility \sphinxcode{\sphinxupquote{Template Check}}
flag that was introduced in 8.10 to help users gradually move their
template polymorphic inductive type definitions outside sections
(\sphinxhref{https://github.com/coq/coq/pull/11546}{\#11546}%
\begin{footnote}[487]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11546}
%
\end{footnote}, by Pierre\sphinxhyphen{}Marie
Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Deprecated \sphinxcode{\sphinxupquote{Shrink Obligations}} flag
(\sphinxhref{https://github.com/coq/coq/pull/11828}{\#11828}%
\begin{footnote}[488]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11828}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Unqualified \sphinxcode{\sphinxupquote{polymorphic}}, \sphinxcode{\sphinxupquote{monomorphic}}, \sphinxcode{\sphinxupquote{template}},
\sphinxcode{\sphinxupquote{notemplate}} attributes (they were deprecated since Coq 8.10).
Use {\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(polymorphic)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(polymorphic)}}}}}, \sphinxcode{\sphinxupquote{universes(monomorphic)}},
{\hyperref[\detokenize{language/core/inductive:coq:attr.universes(template)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(template)}}}}} and \sphinxcode{\sphinxupquote{universes(notemplate)}} instead
(\sphinxhref{https://github.com/coq/coq/pull/11663}{\#11663}%
\begin{footnote}[489]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11663}
%
\end{footnote}, by Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
\sphinxcode{\sphinxupquote{Hide Obligations}} flag
(\sphinxhref{https://github.com/coq/coq/pull/11828}{\#11828}%
\begin{footnote}[490]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11828}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:} Handle the {\hyperref[\detokenize{language/core/modules:coq:attr.local}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{local}}}}} attribute in {\hyperref[\detokenize{language/extensions/canonical:coq:cmd.Canonical-Structure}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Canonical
Structure}}}}} declarations (\sphinxhref{https://github.com/coq/coq/pull/11162}{\#11162}%
\begin{footnote}[491]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11162}
%
\end{footnote}, by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
New attributes supported when defining an inductive type
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:attr.universes(cumulative)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{universes(cumulative)}}}}}, \sphinxcode{\sphinxupquote{universes(noncumulative)}} and
{\hyperref[\detokenize{language/core/variants:coq:attr.private(matching)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{private(matching)}}}}}, which correspond to legacy attributes
\sphinxcode{\sphinxupquote{Cumulative}}, \sphinxcode{\sphinxupquote{NonCumulative}}, and the previously undocumented
\sphinxcode{\sphinxupquote{Private}} (\sphinxhref{https://github.com/coq/coq/pull/11665}{\#11665}%
\begin{footnote}[492]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11665}
%
\end{footnote}, by
Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{proofs/automatic-tactics/auto:creating-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Hint}}}} commands now accept the {\hyperref[\detokenize{language/core/modules:coq:attr.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{export}}}}} locality as
an attribute, allowing to make import\sphinxhyphen{}scoped hints
(\sphinxhref{https://github.com/coq/coq/pull/11812}{\#11812}%
\begin{footnote}[493]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11812}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{addendum/sprop:coq:flag.Cumulative-StrictProp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Cumulative StrictProp}}}}} to control cumulativity of \(\SProp\)
(\sphinxhref{https://github.com/coq/coq/pull/12034}{\#12034}%
\begin{footnote}[494]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12034}
%
\end{footnote}, by Gaëtan
Gilbert).

\end{itemize}


\subparagraph{Commands}
\label{\detokenize{changes:commands}}\begin{quote}
\phantomsection\label{\detokenize{changes:coercions}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The {\hyperref[\detokenize{addendum/implicit-coercions:coq:cmd.Coercion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Coercion}}}}} command has been improved to check the coherence of the
inheritance graph. It checks whether a circular inheritance path of \sphinxcode{\sphinxupquote{C >\sphinxhyphen{}> C}}
is convertible with the identity function or not, then report it as an
ambiguous path if it is not.  The new mechanism does not report ambiguous
paths that are redundant with others. For example, checking the ambiguity of
\sphinxcode{\sphinxupquote{{[}f; g{]}}} and \sphinxcode{\sphinxupquote{{[}f'; g{]}}} is redundant with that of \sphinxcode{\sphinxupquote{{[}f{]}}} and \sphinxcode{\sphinxupquote{{[}f'{]}}} thus will
not be reported
(\sphinxhref{https://github.com/coq/coq/pull/11258}{\#11258}%
\begin{footnote}[495]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11258}
%
\end{footnote},
by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Several commands ({\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.About}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{About}}}}}, ...) now print the
implicit arguments in brackets when printing types (\sphinxhref{https://github.com/coq/coq/pull/11795}{\#11795}%
\begin{footnote}[496]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11795}
%
\end{footnote}, by Simon Boulier).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} The warning when using {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} inside a section
moved from the \sphinxcode{\sphinxupquote{deprecated}} category to the \sphinxcode{\sphinxupquote{fragile}} category,
because there is no plan to remove the functionality at this time
(\sphinxhref{https://github.com/coq/coq/pull/11972}{\#11972}%
\begin{footnote}[497]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11972}
%
\end{footnote}, by Gaëtan
Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Redirect}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Redirect}}}}} now obeys the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Printing-Width}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Width}}}}} and
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.Printing-Depth}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Depth}}}}} options
(\sphinxhref{https://github.com/coq/coq/pull/12358}{\#12358}%
\begin{footnote}[498]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12358}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Recursive OCaml loadpaths are not supported anymore; the command
\sphinxcode{\sphinxupquote{Add Rec ML Path}} has been removed; {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Add-ML-Path}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add ML Path}}}}} is now the
preferred one. We have also dropped support for the non\sphinxhyphen{}qualified
version of the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Add-LoadPath}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add LoadPath}}}}} command, that is to say,
the \sphinxcode{\sphinxupquote{Add LoadPath dir}} version; now,
you must always specify a prefix now using \sphinxcode{\sphinxupquote{Add Loadpath dir as Prefix}}
(\sphinxhref{https://github.com/coq/coq/pull/11618}{\#11618}%
\begin{footnote}[499]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11618}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} undocumented \sphinxcode{\sphinxupquote{Chapter}} command.  Use {\hyperref[\detokenize{language/core/sections:coq:cmd.Section}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Section}}}}}
instead (\sphinxhref{https://github.com/coq/coq/pull/11746}{\#11746}%
\begin{footnote}[500]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11746}
%
\end{footnote}, by Théo
Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} \sphinxcode{\sphinxupquote{SearchAbout}} command that was deprecated since 8.5.
Use {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} instead
(\sphinxhref{https://github.com/coq/coq/pull/11944}{\#11944}%
\begin{footnote}[501]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11944}
%
\end{footnote}, by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
Declaration of arbitrary terms as hints. Global references are now
preferred (\sphinxhref{https://github.com/coq/coq/pull/7791}{\#7791}%
\begin{footnote}[502]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7791}
%
\end{footnote}, by
Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:} \sphinxcode{\sphinxupquote{SearchHead}} in favor of the new \sphinxcode{\sphinxupquote{headconcl:}}
clause of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} (part of \sphinxhref{https://github.com/coq/coq/pull/8855}{\#8855}%
\begin{footnote}[503]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8855}
%
\end{footnote}, by Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{language/extensions/canonical:coq:cmd.Print-Canonical-Projections}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Canonical Projections}}}}} can now take constants as
arguments and prints only the unification rules that involve or are
synthesized from the given constants (\sphinxhref{https://github.com/coq/coq/pull/10747}{\#10747}%
\begin{footnote}[504]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10747}
%
\end{footnote}, by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:} A section variable introduced with {\hyperref[\detokenize{language/core/sections:coq:cmd.Let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let}}}}} can be
declared as a {\hyperref[\detokenize{language/extensions/canonical:coq:cmd.Canonical-Structure}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Canonical Structure}}}}} (\sphinxhref{https://github.com/coq/coq/pull/11164}{\#11164}%
\begin{footnote}[505]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11164}
%
\end{footnote}, by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:} Support for universe bindings and universe contrainsts in
{\hyperref[\detokenize{language/core/sections:coq:cmd.Let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let}}}}} definitions (\sphinxhref{https://github.com/coq/coq/pull/11534}{\#11534}%
\begin{footnote}[506]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11534}
%
\end{footnote}, by Théo Zimmermann).

\phantomsection\label{\detokenize{changes:search}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:} Support for new clauses \sphinxcode{\sphinxupquote{hyp:}}, \sphinxcode{\sphinxupquote{headhyp:}}, \sphinxcode{\sphinxupquote{concl:}},
\sphinxcode{\sphinxupquote{headconcl:}}, \sphinxcode{\sphinxupquote{head:}} and \sphinxcode{\sphinxupquote{is:}} in {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}}.  Support for
complex search queries combining disjunctions, conjunctions and
negations (\sphinxhref{https://github.com/coq/coq/pull/8855}{\#8855}%
\begin{footnote}[507]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8855}
%
\end{footnote}, by Hugo
Herbelin, with ideas from Cyril Cohen and help from Théo
Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
A printing bug in the presence of elimination principles with local definitions
(\sphinxhref{https://github.com/coq/coq/pull/12295}{\#12295}%
\begin{footnote}[508]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12295}
%
\end{footnote},
by Hugo Herbelin; fixes \sphinxhref{https://github.com/coq/coq/pull/12233}{\#12233}%
\begin{footnote}[509]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12233}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Anomalies with {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Proof}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/12296}{\#12296}%
\begin{footnote}[510]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12296}
%
\end{footnote},
by Hugo Herbelin; fixes
\sphinxhref{https://github.com/coq/coq/pull/12234}{\#12234}%
\begin{footnote}[511]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12234}
%
\end{footnote}).

\end{itemize}


\subparagraph{Tools}
\label{\detokenize{changes:id483}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Internal options and behavior of \sphinxcode{\sphinxupquote{coqdep}}. \sphinxcode{\sphinxupquote{coqdep}}
no longer works as a replacement for \sphinxcode{\sphinxupquote{ocamldep}}, thus \sphinxcode{\sphinxupquote{.ml}}
files are not supported as input. Also, several deprecated options
have been removed: \sphinxcode{\sphinxupquote{\sphinxhyphen{}w}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}D}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}mldep}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}prefix}},
\sphinxcode{\sphinxupquote{\sphinxhyphen{}slash}}, and \sphinxcode{\sphinxupquote{\sphinxhyphen{}dumpbox}}. Passing \sphinxcode{\sphinxupquote{\sphinxhyphen{}boot}} to \sphinxcode{\sphinxupquote{coqdep}} will
not load any path by default now, \sphinxcode{\sphinxupquote{\sphinxhyphen{}R/\sphinxhyphen{}Q}} should be used instead
(\sphinxhref{https://github.com/coq/coq/pull/11523}{\#11523}%
\begin{footnote}[512]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11523}
%
\end{footnote} and
\sphinxhref{https://github.com/coq/coq/pull/11589}{\#11589}%
\begin{footnote}[513]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11589}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The order in which the require flags \sphinxcode{\sphinxupquote{\sphinxhyphen{}ri}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}re}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}rfrom}}, etc.
and the option flags \sphinxcode{\sphinxupquote{\sphinxhyphen{}set}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}unset}} are given now matters.  In
particular, it is now possible to interleave the loading of plugins
and the setting of options by choosing the right order for these
flags.  The load flags \sphinxcode{\sphinxupquote{\sphinxhyphen{}l}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}lv}} are still processed afterward
for now (\sphinxhref{https://github.com/coq/coq/pull/11851}{\#11851}%
\begin{footnote}[514]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11851}
%
\end{footnote} and
\sphinxhref{https://github.com/coq/coq/pull/12097}{\#12097}%
\begin{footnote}[515]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12097}
%
\end{footnote},
by Lasse Blaauwbroek).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The \sphinxcode{\sphinxupquote{cleanall}} target of a makefile generated by \sphinxcode{\sphinxupquote{coq\_makefile}}
now erases \sphinxcode{\sphinxupquote{.lia.cache}} and \sphinxcode{\sphinxupquote{.nia.cache}} (\sphinxhref{https://github.com/coq/coq/pull/12006}{\#12006}%
\begin{footnote}[516]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12006}
%
\end{footnote}, by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The output of \sphinxcode{\sphinxupquote{make TIMED=1}} (and therefore the timing targets
such as \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed}} and \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}}) now
displays the full name of the output file being built, rather than
the stem of the rule (which was usually the filename without the
extension, but in general could be anything for user\sphinxhyphen{}defined rules
involving \sphinxcode{\sphinxupquote{\%}}) (\sphinxhref{https://github.com/coq/coq/pull/12126}{\#12126}%
\begin{footnote}[517]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12126}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
When passing \sphinxcode{\sphinxupquote{TIMED=1}} to \sphinxcode{\sphinxupquote{make}} with either Coq's own makefile
or a \sphinxcode{\sphinxupquote{coq\_makefile}}\sphinxhyphen{}made makefile, timing information is now
printed for OCaml files as well (\sphinxhref{https://github.com/coq/coq/pull/12211}{\#12211}%
\begin{footnote}[518]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12211}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The pretty\sphinxhyphen{}timed scripts and targets now print a newline at the end of their
tables, rather than creating text with no trailing newline (\sphinxhref{https://github.com/coq/coq/pull/12368}{\#12368}%
\begin{footnote}[519]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12368}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
The \sphinxcode{\sphinxupquote{\sphinxhyphen{}load\sphinxhyphen{}ml\sphinxhyphen{}source}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}load\sphinxhyphen{}ml\sphinxhyphen{}object}} command\sphinxhyphen{}line options
have been removed; their use was very limited, you can achieve the same adding
additional object files in the linking step or using a plugin
(\sphinxhref{https://github.com/coq/coq/pull/11409}{\#11409}%
\begin{footnote}[520]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11409}
%
\end{footnote}, by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
The confusingly\sphinxhyphen{}named \sphinxcode{\sphinxupquote{\sphinxhyphen{}require}} command\sphinxhyphen{}line option, which was
deprecated since 8.11.  Use the equivalent \sphinxcode{\sphinxupquote{\sphinxhyphen{}require\sphinxhyphen{}import}} / \sphinxcode{\sphinxupquote{\sphinxhyphen{}ri}}
options instead
(\sphinxhref{https://github.com/coq/coq/pull/12005}{\#12005}%
\begin{footnote}[521]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12005}
%
\end{footnote},
by Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
\sphinxcode{\sphinxupquote{\sphinxhyphen{}cumulative\sphinxhyphen{}sprop}} command\sphinxhyphen{}line flag in favor of the new
{\hyperref[\detokenize{addendum/sprop:coq:flag.Cumulative-StrictProp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Cumulative StrictProp}}}}} flag (\sphinxhref{https://github.com/coq/coq/pull/12034}{\#12034}%
\begin{footnote}[522]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12034}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A new documentation environment \sphinxcode{\sphinxupquote{details}} to make certain portion
of a Coq document foldable.  See {\hyperref[\detokenize{using/tools/coqdoc:coqdoc-hide-show}]{\sphinxcrossref{\DUrole{std,std-ref}{Hiding / Showing parts of the source}}}}
(\sphinxhref{https://github.com/coq/coq/pull/10592}{\#10592}%
\begin{footnote}[523]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10592}
%
\end{footnote},
by Thomas Letan).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The \sphinxcode{\sphinxupquote{make\sphinxhyphen{}both\sphinxhyphen{}single\sphinxhyphen{}timing\sphinxhyphen{}files.py}} script now accepts a
\sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}fuzz=N}} parameter on the command line which determines how many
characters two lines may be offset in the "before" and "after"
timing logs while still being considered the same line.  When
invoking this script via the \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}single\sphinxhyphen{}time\sphinxhyphen{}diff}}
target in a \sphinxcode{\sphinxupquote{Makefile}} made by \sphinxcode{\sphinxupquote{coq\_makefile}}, you can set this
argument by passing \sphinxcode{\sphinxupquote{TIMING\_FUZZ=N}} to \sphinxcode{\sphinxupquote{make}} (\sphinxhref{https://github.com/coq/coq/pull/11302}{\#11302}%
\begin{footnote}[524]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11302}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The \sphinxcode{\sphinxupquote{make\sphinxhyphen{}one\sphinxhyphen{}time\sphinxhyphen{}file.py}} and \sphinxcode{\sphinxupquote{make\sphinxhyphen{}both\sphinxhyphen{}time\sphinxhyphen{}files.py}}
scripts now accept a \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}real}} parameter on the command line to
print real times rather than user times in the tables.  The
\sphinxcode{\sphinxupquote{make\sphinxhyphen{}both\sphinxhyphen{}single\sphinxhyphen{}timing\sphinxhyphen{}files.py}} script accepts a \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}user}}
parameter to use user times.  When invoking these scripts via the
\sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed}} or \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}} or
\sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}single\sphinxhyphen{}time\sphinxhyphen{}diff}} targets in a \sphinxcode{\sphinxupquote{Makefile}} made by
\sphinxcode{\sphinxupquote{coq\_makefile}}, you can set this argument by passing
\sphinxcode{\sphinxupquote{TIMING\_REAL=1}} (to pass \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}real}}) or \sphinxcode{\sphinxupquote{TIMING\_REAL=0}} (to pass
\sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}user}}) to \sphinxcode{\sphinxupquote{make}} (\sphinxhref{https://github.com/coq/coq/pull/11302}{\#11302}%
\begin{footnote}[525]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11302}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Coq's build system now supports both \sphinxcode{\sphinxupquote{TIMING\_FUZZ}},
\sphinxcode{\sphinxupquote{TIMING\_SORT\_BY}}, and \sphinxcode{\sphinxupquote{TIMING\_REAL}} just like a \sphinxcode{\sphinxupquote{Makefile}}
made by \sphinxcode{\sphinxupquote{coq\_makefile}} (\sphinxhref{https://github.com/coq/coq/pull/11302}{\#11302}%
\begin{footnote}[526]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11302}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The \sphinxcode{\sphinxupquote{make\sphinxhyphen{}one\sphinxhyphen{}time\sphinxhyphen{}file.py}} and \sphinxcode{\sphinxupquote{make\sphinxhyphen{}both\sphinxhyphen{}time\sphinxhyphen{}files.py}}
scripts now include peak memory usage information in the tables (can
be turned off by the \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}no\sphinxhyphen{}include\sphinxhyphen{}mem}} command\sphinxhyphen{}line parameter),
and a \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}sort\sphinxhyphen{}by\sphinxhyphen{}mem}} parameter to sort the tables by memory
rather than time.  When invoking these scripts via the
\sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed}} or \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}} targets in a
\sphinxcode{\sphinxupquote{Makefile}} made by \sphinxcode{\sphinxupquote{coq\_makefile}}, you can set this argument by
passing \sphinxcode{\sphinxupquote{TIMING\_INCLUDE\_MEM=0}} (to pass \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}no\sphinxhyphen{}include\sphinxhyphen{}mem}}) and
\sphinxcode{\sphinxupquote{TIMING\_SORT\_BY\_MEM=1}} (to pass \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}sort\sphinxhyphen{}by\sphinxhyphen{}mem}}) to \sphinxcode{\sphinxupquote{make}}
(\sphinxhref{https://github.com/coq/coq/pull/11606}{\#11606}%
\begin{footnote}[527]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11606}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Coq's build system now supports both \sphinxcode{\sphinxupquote{TIMING\_INCLUDE\_MEM}} and
\sphinxcode{\sphinxupquote{TIMING\_SORT\_BY\_MEM}} just like a \sphinxcode{\sphinxupquote{Makefile}} made by
\sphinxcode{\sphinxupquote{coq\_makefile}} (\sphinxhref{https://github.com/coq/coq/pull/11606}{\#11606}%
\begin{footnote}[528]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11606}
%
\end{footnote},
by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
New \sphinxcode{\sphinxupquote{coqc}} / \sphinxcode{\sphinxupquote{coqtop}} option \sphinxcode{\sphinxupquote{\sphinxhyphen{}boot}} that will not bind the
\sphinxcode{\sphinxupquote{Coq}} library prefix by default
(\sphinxhref{https://github.com/coq/coq/pull/11617}{\#11617}%
\begin{footnote}[529]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11617}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Definitions in coqdoc link to themselves, giving access in html to their own url
(\sphinxhref{https://github.com/coq/coq/pull/12026}{\#12026}%
\begin{footnote}[530]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12026}
%
\end{footnote},
by Hugo Herbelin; granting \sphinxhref{https://github.com/coq/coq/pull/7093}{\#7093}%
\begin{footnote}[531]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7093}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Hyperlinks on bound variables in coqdoc
(\sphinxhref{https://github.com/coq/coq/pull/12033}{\#12033}%
\begin{footnote}[532]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12033}
%
\end{footnote},
by Hugo Herbelin; it incidentally fixes
\sphinxhref{https://github.com/coq/coq/pull/7697}{\#7697}%
\begin{footnote}[533]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7697}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Highlighting of link targets in coqdoc
(\sphinxhref{https://github.com/coq/coq/pull/12091}{\#12091}%
\begin{footnote}[534]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12091}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
The various timing targets for Coq's standard library now correctly
display and label the "before" and "after" columns, rather than
mixing them up (\sphinxhref{https://github.com/coq/coq/pull/11302}{\#11302}%
\begin{footnote}[535]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11302}
%
\end{footnote}
fixes \sphinxhref{https://github.com/coq/coq/issues/11301}{\#11301}%
\begin{footnote}[536]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11301}
%
\end{footnote}, by Jason
Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
The sorting order of the timing script \sphinxcode{\sphinxupquote{make\sphinxhyphen{}both\sphinxhyphen{}time\sphinxhyphen{}files.py}}
and the target \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}} is now deterministic even
when the sorting order is \sphinxcode{\sphinxupquote{absolute}} or \sphinxcode{\sphinxupquote{diff}}; previously the
relative ordering of two files with identical times was
non\sphinxhyphen{}deterministic (\sphinxhref{https://github.com/coq/coq/pull/11606}{\#11606}%
\begin{footnote}[537]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11606}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Fields of a record tuple now link in coqdoc to their definition
(\sphinxhref{https://github.com/coq/coq/pull/12027}{\#12027}%
\begin{footnote}[538]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12027}
%
\end{footnote}, fixes
\sphinxhref{https://github.com/coq/coq/issues/3415}{\#3415}%
\begin{footnote}[539]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/3415}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
\sphinxcode{\sphinxupquote{coqdoc}} now reports the location of a mismatched opening \sphinxcode{\sphinxupquote{{[}{[}}}
instead of throwing an uninformative exception
(\sphinxhref{https://github.com/coq/coq/pull/12037}{\#12037}%
\begin{footnote}[540]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12037}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9670}{\#9670}%
\begin{footnote}[541]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9670}
%
\end{footnote},
by Xia Li\sphinxhyphen{}yao).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
coqchk incorrectly reporting names from opaque modules as axioms
(\sphinxhref{https://github.com/coq/coq/pull/12076}{\#12076}%
\begin{footnote}[542]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12076}
%
\end{footnote},
by Pierre Roux; fixes \sphinxhref{https://github.com/coq/coq/issues/5030}{\#5030}%
\begin{footnote}[543]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/5030}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
coq\_makefile\sphinxhyphen{}generated \sphinxcode{\sphinxupquote{Makefile}}s \sphinxcode{\sphinxupquote{pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}} target
no longer raises Python exceptions in the rare corner case where the
log of times contains no files (\sphinxhref{https://github.com/coq/coq/pull/12388}{\#12388}%
\begin{footnote}[544]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12388}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/pull/12387}{\#12387}%
\begin{footnote}[545]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12387}
%
\end{footnote}, by Jason Gross).

\end{itemize}


\subparagraph{CoqIDE}
\label{\detokenize{changes:id518}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
"Tactic" menu from CoqIDE which had been unmaintained for a number of years
(\sphinxhref{https://github.com/coq/coq/pull/11414}{\#11414}%
\begin{footnote}[546]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11414}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
"Revert all buffers" command from CoqIDE which had been broken for a long time
(\sphinxhref{https://github.com/coq/coq/pull/11415}{\#11415}%
\begin{footnote}[547]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11415}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}


\subparagraph{Standard library}
\label{\detokenize{changes:id521}}\label{\detokenize{changes:id522}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Notations \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}|{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}|{]}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}||{\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}||{]}}}} for morphisms from 63\sphinxhyphen{}bit
integers to \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{zn2z} \DUrole{name}{int}}} have been removed in favor of
\sphinxcode{\sphinxupquote{\DUrole{notation}{φ({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{Φ({\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} respectively. These notations were
breaking Ltac parsing (\sphinxhref{https://github.com/coq/coq/pull/11686}{\#11686}%
\begin{footnote}[548]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11686}
%
\end{footnote},
by Maxime Dénès).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The names of \sphinxcode{\sphinxupquote{Sorted\_sort}} and \sphinxcode{\sphinxupquote{LocallySorted\_sort}} in \sphinxcode{\sphinxupquote{Coq.Sorting.MergeSort}}
have been swapped to appropriately reflect their meanings
(\sphinxhref{https://github.com/coq/coq/pull/11885}{\#11885}%
\begin{footnote}[549]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11885}
%
\end{footnote},
by Lysxia).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Notations \sphinxcode{\sphinxupquote{\DUrole{operator}{<=?}}} and \sphinxcode{\sphinxupquote{\DUrole{operator}{<?}}} from \sphinxcode{\sphinxupquote{Coq.Structures.Orders}} and
\sphinxcode{\sphinxupquote{Coq.Sorting.Mergesort.NatOrder}} are now at level 70 rather than
35, so as to be compatible with the notations defined everywhere
else in the standard library.  This may require re\sphinxhyphen{}parenthesizing
some expressions.  These notations were breaking the ability to
import modules from the standard library that were otherwise
compatible (fixes \sphinxhref{https://github.com/coq/coq/issues/11890}{\#11890}%
\begin{footnote}[550]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11890}
%
\end{footnote}, \sphinxhref{https://github.com/coq/coq/pull/11891}{\#11891}%
\begin{footnote}[551]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11891}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The level of \sphinxcode{\sphinxupquote{\DUrole{name,builtin,pseudo}{≡}}} in \sphinxcode{\sphinxupquote{Coq.Numbers.Cyclic.Int63.Int63}} is now 70,
no associativity, in line with \sphinxcode{\sphinxupquote{\DUrole{operator}{=}}}.  Note that this is a minor
incompatibility with developments that declare their own \sphinxcode{\sphinxupquote{\DUrole{name,builtin,pseudo}{≡}}}
notation and import \sphinxcode{\sphinxupquote{Int63}} (fixes \sphinxhref{https://github.com/coq/coq/issues/11905}{\#11905}%
\begin{footnote}[552]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11905}
%
\end{footnote}, \sphinxhref{https://github.com/coq/coq/pull/11909}{\#11909}%
\begin{footnote}[553]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11909}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
No longer re\sphinxhyphen{}export \sphinxcode{\sphinxupquote{ListNotations}} from \sphinxcode{\sphinxupquote{Program}} (\sphinxcode{\sphinxupquote{Program.Syntax}})
(\sphinxhref{https://github.com/coq/coq/pull/11992}{\#11992}%
\begin{footnote}[554]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11992}
%
\end{footnote},
by Antonio Nikishaev).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
It is now possible to import the \sphinxcode{\sphinxupquote{\DUrole{name}{nsatz}}} machinery without
transitively depending on the axioms of the real numbers nor of
classical logic by loading \sphinxcode{\sphinxupquote{Coq.nsatz.NsatzTactic}} rather than
\sphinxcode{\sphinxupquote{Coq.nsatz.Nsatz}}.  Note that some constants have changed kernel
names, living in \sphinxcode{\sphinxupquote{Coq.nsatz.NsatzTactic}} rather than
\sphinxcode{\sphinxupquote{Coq.nsatz.Nsatz}}; this might cause minor incompatibilities that
can be fixed by actually running \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Import} \DUrole{name}{Nsatz}}} rather than
relying on absolute names (\sphinxhref{https://github.com/coq/coq/pull/12073}{\#12073}%
\begin{footnote}[555]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12073}
%
\end{footnote}, by Jason Gross; fixes
\sphinxhref{https://github.com/coq/coq/issues/5445}{\#5445}%
\begin{footnote}[556]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/5445}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
new lemma \sphinxcode{\sphinxupquote{NoDup\_incl\_NoDup}} in \sphinxcode{\sphinxupquote{List.v}}
to remove useless hypothesis \sphinxcode{\sphinxupquote{NoDup l'}} in \sphinxcode{\sphinxupquote{Sorting.Permutation.NoDup\_Permutation\_bis}}
(\sphinxhref{https://github.com/coq/coq/pull/12119}{\#12120}%
\begin{footnote}[557]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12119}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
{\hyperref[\detokenize{language/core/inductive:coq:cmd.Fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoints}}}}} of the standard library without a recursive call turned
into ordinary {\hyperref[\detokenize{language/core/definitions:coq:cmd.Definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definitions}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/12121}{\#12121}%
\begin{footnote}[558]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12121}
%
\end{footnote},
by Hugo Herbelin; fixes \sphinxhref{https://github.com/coq/coq/pull/11903}{\#11903}%
\begin{footnote}[559]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11903}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
\sphinxcode{\sphinxupquote{Bool.leb}} in favor of \sphinxcode{\sphinxupquote{Bool.le}}. The definition of \sphinxcode{\sphinxupquote{Bool.le}}
is made local to avoid conflicts with \sphinxcode{\sphinxupquote{Nat.le}}. As a consequence,
previous calls to \sphinxcode{\sphinxupquote{leb}} based on importing \sphinxcode{\sphinxupquote{Bool}} should now be
qualified into \sphinxcode{\sphinxupquote{Bool.le}} even if \sphinxcode{\sphinxupquote{Bool}} is imported
(\sphinxhref{https://github.com/coq/coq/pull/12162}{\#12162}%
\begin{footnote}[560]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12162}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:} Theorem \sphinxcode{\sphinxupquote{\DUrole{name}{bezout\_comm}}} for natural numbers
(\sphinxhref{https://github.com/coq/coq/pull/11127}{\#11127}%
\begin{footnote}[561]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11127}
%
\end{footnote}, by Daniel de Rauglaudre).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added}
\sphinxcode{\sphinxupquote{\DUrole{name}{rew} \DUrole{name}{dependent}}} notations for the dependent version of
\sphinxcode{\sphinxupquote{\DUrole{name}{rew}}} in \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Init}\DUrole{operator}{.}\DUrole{name}{Logic}\DUrole{operator}{.}\DUrole{name}{EqNotations}}} to improve the display
and parsing of \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} statements on \sphinxcode{\sphinxupquote{\DUrole{name}{Logic}\DUrole{operator}{.}\DUrole{name}{eq}}} (\sphinxhref{https://github.com/coq/coq/pull/11240}{\#11240}%
\begin{footnote}[562]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11240}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas about lists:
\begin{itemize}
\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{In}}: \sphinxcode{\sphinxupquote{in\_elt}}, \sphinxcode{\sphinxupquote{in\_elt\_inv}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{nth}}: \sphinxcode{\sphinxupquote{app\_nth2\_plus}}, \sphinxcode{\sphinxupquote{nth\_middle}}, \sphinxcode{\sphinxupquote{nth\_ext}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{last}}: \sphinxcode{\sphinxupquote{last\_last}}, \sphinxcode{\sphinxupquote{removelast\_last}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{remove}}: \sphinxcode{\sphinxupquote{remove\_cons}}, \sphinxcode{\sphinxupquote{remove\_app}}, \sphinxcode{\sphinxupquote{notin\_remove}}, \sphinxcode{\sphinxupquote{in\_remove}}, \sphinxcode{\sphinxupquote{in\_in\_remove}}, \sphinxcode{\sphinxupquote{remove\_remove\_comm}}, \sphinxcode{\sphinxupquote{remove\_remove\_eq}}, \sphinxcode{\sphinxupquote{remove\_length\_le}}, \sphinxcode{\sphinxupquote{remove\_length\_lt}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{concat}}: \sphinxcode{\sphinxupquote{in\_concat}}, \sphinxcode{\sphinxupquote{remove\_concat}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{map}} and \sphinxcode{\sphinxupquote{flat\_map}}: \sphinxcode{\sphinxupquote{map\_last}}, \sphinxcode{\sphinxupquote{map\_eq\_cons}}, \sphinxcode{\sphinxupquote{map\_eq\_app}}, \sphinxcode{\sphinxupquote{flat\_map\_app}}, \sphinxcode{\sphinxupquote{flat\_map\_ext}}, \sphinxcode{\sphinxupquote{nth\_nth\_nth\_map}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{incl}}: \sphinxcode{\sphinxupquote{incl\_nil\_l}}, \sphinxcode{\sphinxupquote{incl\_l\_nil}}, \sphinxcode{\sphinxupquote{incl\_cons\_inv}}, \sphinxcode{\sphinxupquote{incl\_app\_app}}, \sphinxcode{\sphinxupquote{incl\_app\_inv}}, \sphinxcode{\sphinxupquote{remove\_incl}}, \sphinxcode{\sphinxupquote{incl\_map}}, \sphinxcode{\sphinxupquote{incl\_filter}}, \sphinxcode{\sphinxupquote{incl\_Forall\_in\_iff}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{NoDup}} and \sphinxcode{\sphinxupquote{nodup}}: \sphinxcode{\sphinxupquote{NoDup\_rev}}, \sphinxcode{\sphinxupquote{NoDup\_filter}}, \sphinxcode{\sphinxupquote{nodup\_incl}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{Exists}} and \sphinxcode{\sphinxupquote{Forall}}: \sphinxcode{\sphinxupquote{Exists\_nth}}, \sphinxcode{\sphinxupquote{Exists\_app}}, \sphinxcode{\sphinxupquote{Exists\_rev}}, \sphinxcode{\sphinxupquote{Exists\_fold\_right}}, \sphinxcode{\sphinxupquote{incl\_Exists}}, \sphinxcode{\sphinxupquote{Forall\_nth}}, \sphinxcode{\sphinxupquote{Forall\_app}}, \sphinxcode{\sphinxupquote{Forall\_elt}}, \sphinxcode{\sphinxupquote{Forall\_rev}}, \sphinxcode{\sphinxupquote{Forall\_fold\_right}}, \sphinxcode{\sphinxupquote{incl\_Forall}}, \sphinxcode{\sphinxupquote{map\_ext\_Forall}}, \sphinxcode{\sphinxupquote{Exists\_or}}, \sphinxcode{\sphinxupquote{Exists\_or\_inv}}, \sphinxcode{\sphinxupquote{Forall\_and}}, \sphinxcode{\sphinxupquote{Forall\_and\_inv}}, \sphinxcode{\sphinxupquote{exists\_Forall}}, \sphinxcode{\sphinxupquote{Forall\_image}}, \sphinxcode{\sphinxupquote{concat\_nil\_Forall}}, \sphinxcode{\sphinxupquote{in\_flat\_map\_Exists}}, \sphinxcode{\sphinxupquote{notin\_flat\_map\_Forall}}

\item {} 
\sphinxAtStartPar
properties of \sphinxcode{\sphinxupquote{repeat}}: \sphinxcode{\sphinxupquote{repeat\_cons}}, \sphinxcode{\sphinxupquote{repeat\_to\_concat}}

\item {} 
\sphinxAtStartPar
definitions and properties of \sphinxcode{\sphinxupquote{list\_sum}} and \sphinxcode{\sphinxupquote{list\_max}}: \sphinxcode{\sphinxupquote{list\_sum\_app}}, \sphinxcode{\sphinxupquote{list\_max\_app}}, \sphinxcode{\sphinxupquote{list\_max\_le}}, \sphinxcode{\sphinxupquote{list\_max\_lt}}

\item {} 
\sphinxAtStartPar
misc: \sphinxcode{\sphinxupquote{elt\_eq\_unit}}, \sphinxcode{\sphinxupquote{last\_length}}, \sphinxcode{\sphinxupquote{rev\_eq\_app}}, \sphinxcode{\sphinxupquote{removelast\_firstn\_len}}, \sphinxcode{\sphinxupquote{cons\_seq}}, \sphinxcode{\sphinxupquote{seq\_S}}

\end{itemize}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/11249}{\#11249}%
\begin{footnote}[563]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11249}
%
\end{footnote}, \sphinxhref{https://github.com/coq/coq/pull/12237}{\#12237}%
\begin{footnote}[564]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12237}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Well\sphinxhyphen{}founded induction principles for \sphinxcode{\sphinxupquote{nat}}: \sphinxcode{\sphinxupquote{lt\_wf\_rect1}}, \sphinxcode{\sphinxupquote{lt\_wf\_rect}}, \sphinxcode{\sphinxupquote{gt\_wf\_rect}}, \sphinxcode{\sphinxupquote{lt\_wf\_double\_rect}}
(\sphinxhref{https://github.com/coq/coq/pull/11335}{\#11335}%
\begin{footnote}[565]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11335}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{remove'}} and \sphinxcode{\sphinxupquote{count\_occ'}} over lists,
alternatives to \sphinxcode{\sphinxupquote{remove}} and \sphinxcode{\sphinxupquote{count\_occ}} based on \sphinxcode{\sphinxupquote{filter}}
(\sphinxhref{https://github.com/coq/coq/pull/11350}{\#11350}%
\begin{footnote}[566]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11350}
%
\end{footnote},
by Yishuai Li).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Facts about \sphinxcode{\sphinxupquote{N.iter}} and \sphinxcode{\sphinxupquote{Pos.iter}}:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{N.iter\_swap\_gen}}, \sphinxcode{\sphinxupquote{N.iter\_swap}}, \sphinxcode{\sphinxupquote{N.iter\_succ}}, \sphinxcode{\sphinxupquote{N.iter\_succ\_r}}, \sphinxcode{\sphinxupquote{N.iter\_add}}, \sphinxcode{\sphinxupquote{N.iter\_ind}}, \sphinxcode{\sphinxupquote{N.iter\_invariant}};

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Pos.iter\_succ\_r}}, \sphinxcode{\sphinxupquote{Pos.iter\_ind}}.

\end{itemize}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/11880}{\#11880}%
\begin{footnote}[567]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11880}
%
\end{footnote},
by Lysxia).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Facts about \sphinxcode{\sphinxupquote{Permutation}}:
\begin{itemize}
\item {} 
\sphinxAtStartPar
structure: \sphinxcode{\sphinxupquote{Permutation\_refl'}}, \sphinxcode{\sphinxupquote{Permutation\_morph\_transp}}

\item {} 
\sphinxAtStartPar
compatibilities: \sphinxcode{\sphinxupquote{Permutation\_app\_rot}}, \sphinxcode{\sphinxupquote{Permutation\_app\_swap\_app}}, \sphinxcode{\sphinxupquote{Permutation\_app\_middle}}, \sphinxcode{\sphinxupquote{Permutation\_middle2}}, \sphinxcode{\sphinxupquote{Permutation\_elt}}, \sphinxcode{\sphinxupquote{Permutation\_Forall}}, \sphinxcode{\sphinxupquote{Permutation\_Exists}}, \sphinxcode{\sphinxupquote{Permutation\_Forall2}}, \sphinxcode{\sphinxupquote{Permutation\_flat\_map}}, \sphinxcode{\sphinxupquote{Permutation\_list\_sum}}, \sphinxcode{\sphinxupquote{Permutation\_list\_max}}

\item {} 
\sphinxAtStartPar
inversions: \sphinxcode{\sphinxupquote{Permutation\_app\_inv\_m}}, \sphinxcode{\sphinxupquote{Permutation\_vs\_elt\_inv}}, \sphinxcode{\sphinxupquote{Permutation\_vs\_cons\_inv}}, \sphinxcode{\sphinxupquote{Permutation\_vs\_cons\_cons\_inv}}, \sphinxcode{\sphinxupquote{Permutation\_map\_inv}}, \sphinxcode{\sphinxupquote{Permutation\_image}}, \sphinxcode{\sphinxupquote{Permutation\_elt\_map\_inv}}

\item {} 
\sphinxAtStartPar
length\sphinxhyphen{}preserving definition by means of transpositions \sphinxcode{\sphinxupquote{Permutation\_transp}} with associated properties: \sphinxcode{\sphinxupquote{Permutation\_transp\_sym}}, \sphinxcode{\sphinxupquote{Permutation\_transp\_equiv}}, \sphinxcode{\sphinxupquote{Permutation\_transp\_cons}}, \sphinxcode{\sphinxupquote{Permutation\_Permutation\_transp}}, \sphinxcode{\sphinxupquote{Permutation\_ind\_transp}}

\end{itemize}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/11946}{\#11946}%
\begin{footnote}[568]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11946}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Notations for sigma types: \sphinxcode{\sphinxupquote{\{ x \& P \& Q \}}}, \sphinxcode{\sphinxupquote{\{ ' pat \& P \}}}, \sphinxcode{\sphinxupquote{\{ ' pat \& P \& Q \}}}
(\sphinxhref{https://github.com/coq/coq/pull/11957}{\#11957}%
\begin{footnote}[569]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11957}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Order relations \sphinxcode{\sphinxupquote{lt}} and \sphinxcode{\sphinxupquote{compare}} added in \sphinxcode{\sphinxupquote{Bool.Bool}}.
Order properties for \sphinxcode{\sphinxupquote{bool}} added in \sphinxcode{\sphinxupquote{Bool.BoolOrder}} as well as two modules \sphinxcode{\sphinxupquote{Bool\_as\_OT}} and \sphinxcode{\sphinxupquote{Bool\_as\_DT}} in \sphinxcode{\sphinxupquote{Structures.OrdersEx}}
(\sphinxhref{https://github.com/coq/coq/pull/12008}{\#12008}%
\begin{footnote}[570]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12008}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Properties of some operations on vectors:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{nth\_order}}: \sphinxcode{\sphinxupquote{nth\_order\_hd}}, \sphinxcode{\sphinxupquote{nth\_order\_tl}}, \sphinxcode{\sphinxupquote{nth\_order\_ext}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{replace}}: \sphinxcode{\sphinxupquote{nth\_order\_replace\_eq}}, \sphinxcode{\sphinxupquote{nth\_order\_replace\_neq}}, \sphinxcode{\sphinxupquote{replace\_id}}, \sphinxcode{\sphinxupquote{replace\_replace\_eq}}, \sphinxcode{\sphinxupquote{replace\_replace\_neq}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{map}}: \sphinxcode{\sphinxupquote{map\_id}}, \sphinxcode{\sphinxupquote{map\_map}}, \sphinxcode{\sphinxupquote{map\_ext\_in}}, \sphinxcode{\sphinxupquote{map\_ext}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Forall}} and \sphinxcode{\sphinxupquote{Forall2}}: \sphinxcode{\sphinxupquote{Forall\_impl}}, \sphinxcode{\sphinxupquote{Forall\_forall}}, \sphinxcode{\sphinxupquote{Forall\_nth\_order}}, \sphinxcode{\sphinxupquote{Forall2\_nth\_order}}

\end{itemize}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/12014}{\#12014}%
\begin{footnote}[571]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12014}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Lemmas
\sphinxcode{\sphinxupquote{\DUrole{name}{orb\_negb\_l}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{andb\_negb\_l}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_true\_iff}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_false\_iff}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_true\_r}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_false\_r}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_true\_l}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_false\_l}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_same}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_contrapositive}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_negb}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_curry}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_andb\_distrib\_r}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_orb\_distrib\_r}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{implb\_orb\_distrib\_l}}} in library \sphinxcode{\sphinxupquote{\DUrole{name}{Bool}}}
(\sphinxhref{https://github.com/coq/coq/pull/12018}{\#12018}%
\begin{footnote}[572]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12018}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Definition and properties of cyclic permutations / circular shifts: \sphinxcode{\sphinxupquote{CPermutation}}
(\sphinxhref{https://github.com/coq/coq/pull/12031}{\#12031}%
\begin{footnote}[573]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12031}
%
\end{footnote},
by Olivier Laurent).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{Structures.OrderedTypeEx.Ascii\_as\_OT}}
(\sphinxhref{https://github.com/coq/coq/pull/12044}{\#12044}%
\begin{footnote}[574]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12044}
%
\end{footnote},
by formalize.eth (\sphinxhref{mailto:formalize@protonmail.com}{formalize@protonmail.com})).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Rewrote \sphinxcode{\sphinxupquote{Structures.OrderedTypeEx.String\_as\_OT.compare}}
to avoid huge proof terms
(\sphinxhref{https://github.com/coq/coq/pull/12044}{\#12044}%
\begin{footnote}[575]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12044}
%
\end{footnote},
by formalize.eth (\sphinxhref{mailto:formalize@protonmail.com}{formalize@protonmail.com});
fixes \sphinxhref{https://github.com/coq/coq/issues/12015}{\#12015}%
\begin{footnote}[576]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12015}
%
\end{footnote}).

\end{itemize}


\subparagraph{Reals library}
\label{\detokenize{changes:reals-library}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Cleanup of names in the Reals theory: replaced \sphinxcode{\sphinxupquote{tan\_is\_inj}} with
\sphinxcode{\sphinxupquote{tan\_inj}} and replaced \sphinxcode{\sphinxupquote{atan\_right\_inv}} with \sphinxcode{\sphinxupquote{tan\_atan}} \sphinxhyphen{}
compatibility notations are provided. Moved various auxiliary lemmas
from \sphinxcode{\sphinxupquote{Ratan.v}} to more appropriate places
(\sphinxhref{https://github.com/coq/coq/pull/9803}{\#9803}%
\begin{footnote}[577]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9803}
%
\end{footnote},
by Laurent Théry and Michael Soegtrop).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Replace \sphinxcode{\sphinxupquote{CRzero}} and \sphinxcode{\sphinxupquote{CRone}} by \sphinxcode{\sphinxupquote{CR\_of\_Q 0}} and \sphinxcode{\sphinxupquote{CR\_of\_Q 1}} in
\sphinxcode{\sphinxupquote{ConstructiveReals}}.  Use implicit arguments for
\sphinxcode{\sphinxupquote{ConstructiveReals}}. Move \sphinxcode{\sphinxupquote{ConstructiveReals}} into new directory
\sphinxcode{\sphinxupquote{Abstract}}. Remove imports of implementations inside those
\sphinxcode{\sphinxupquote{Abstract}} files. Move implementation by means of Cauchy sequences
in new directory \sphinxcode{\sphinxupquote{Cauchy}}.  Split files \sphinxcode{\sphinxupquote{ConstructiveMinMax}} and
\sphinxcode{\sphinxupquote{ConstructivePower}}.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The constructive reals modules are marked as experimental.
\end{sphinxadmonition}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/11725}{\#11725}%
\begin{footnote}[578]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11725}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/12287}{\#12287}%
\begin{footnote}[579]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12287}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/pull/12288}{\#12288}%
\begin{footnote}[580]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12288}
%
\end{footnote},
by Vincent Semeria).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Type \sphinxcode{\sphinxupquote{RList}} has been removed.  All uses have been replaced by \sphinxcode{\sphinxupquote{list R}}.
Functions from \sphinxcode{\sphinxupquote{RList}} named \sphinxcode{\sphinxupquote{In}}, \sphinxcode{\sphinxupquote{Rlength}}, \sphinxcode{\sphinxupquote{cons\_Rlist}}, \sphinxcode{\sphinxupquote{app\_Rlist}}
have also been removed as they are essentially the same as \sphinxcode{\sphinxupquote{In}}, \sphinxcode{\sphinxupquote{length}},
\sphinxcode{\sphinxupquote{app}}, and \sphinxcode{\sphinxupquote{map}} from \sphinxcode{\sphinxupquote{List}}, modulo the following changes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{RList.In x (RList.cons a l)}} used to be convertible to
\sphinxcode{\sphinxupquote{(x = a) \textbackslash{}/ RList.In x l}},
but \sphinxcode{\sphinxupquote{List.In x (a :: l)}} is convertible to
\sphinxcode{\sphinxupquote{(a = x) \textbackslash{}/ List.In l}}.
The equality is reversed.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{app\_Rlist}} and \sphinxcode{\sphinxupquote{List.map}} take arguments in different order.

\end{itemize}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/11404}{\#11404}%
\begin{footnote}[581]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11404}
%
\end{footnote},
by Yves Bertot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
inverse trigonometric functions \sphinxcode{\sphinxupquote{asin}} and \sphinxcode{\sphinxupquote{acos}} with lemmas for
the derivatives, bounds and special values of these functions; an
extensive set of identities between trigonometric functions and
their inverse functions; lemmas for the injectivity of sine and
cosine; lemmas on the derivative of the inverse of decreasing
functions and on the derivative of horizontally mirrored functions;
various generic auxiliary lemmas and definitions for \sphinxcode{\sphinxupquote{Rsqr}}, \sphinxcode{\sphinxupquote{sqrt}},
\sphinxcode{\sphinxupquote{posreal}} and others
(\sphinxhref{https://github.com/coq/coq/pull/9803}{\#9803}%
\begin{footnote}[582]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9803}
%
\end{footnote},
by Laurent Théry and Michael Soegtrop).

\end{itemize}


\subparagraph{Extraction}
\label{\detokenize{changes:extraction}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Support for better extraction of strings in OCaml and Haskell:
\sphinxcode{\sphinxupquote{ExtOcamlNativeString}} provides bindings from the Coq \sphinxcode{\sphinxupquote{String}} type to
the OCaml \sphinxcode{\sphinxupquote{string}} type, and string literals can be extracted to literals,
both in OCaml and Haskell (\sphinxhref{https://github.com/coq/coq/pull/10486}{\#10486}%
\begin{footnote}[583]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10486}
%
\end{footnote}, by Xavier Leroy, with help from
Maxime Dénès, review by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
In Haskell extraction with \sphinxcode{\sphinxupquote{ExtrHaskellString}}, equality comparisons on
strings and characters are now guaranteed to be uniquely well\sphinxhyphen{}typed, even in
very polymorphic contexts under \sphinxcode{\sphinxupquote{unsafeCoerce}}; this is achieved by adding
type annotations to the extracted code, and by making \sphinxcode{\sphinxupquote{ExtrHaskellString}}
export \sphinxcode{\sphinxupquote{ExtrHaskellBasic}} (\sphinxhref{https://github.com/coq/coq/pull/12263}{\#12263}%
\begin{footnote}[584]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12263}
%
\end{footnote}, by Jason Gross, fixes \sphinxhref{https://github.com/coq/coq/issues/12257}{\#12257}%
\begin{footnote}[585]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12257}
%
\end{footnote} and \sphinxhref{https://github.com/coq/coq/issues/12258}{\#12258}%
\begin{footnote}[586]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12258}
%
\end{footnote}).

\end{itemize}


\subparagraph{Reference manual}
\label{\detokenize{changes:refman}}\label{\detokenize{changes:id562}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The reference manual has been restructured to get a more logical
organization.  In the new version, there are fewer top\sphinxhyphen{}level
chapters, and, in the HTML format, chapters are split into smaller
pages.  This is still a work in progress and further restructuring
is expected in the next versions of Coq
(\sphinxhref{https://github.com/coq/ceps/pull/43}{CEP\#43}%
\begin{footnote}[587]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/ceps/pull/43}
%
\end{footnote}, implemented in
\sphinxhref{https://github.com/coq/coq/pull/11601}{\#11601}%
\begin{footnote}[588]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11601}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11871}{\#11871}%
\begin{footnote}[589]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11871}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11914}{\#11914}%
\begin{footnote}[590]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11914}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/12148}{\#12148}%
\begin{footnote}[591]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12148}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/12172}{\#12172}%
\begin{footnote}[592]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12172}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/12239}{\#12239}%
\begin{footnote}[593]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12239}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/pull/12330}{\#12330}%
\begin{footnote}[594]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12330}
%
\end{footnote},
effort inspired by Matthieu Sozeau, led by Théo Zimmermann, with
help and reviews of Jim Fehrle, Clément Pit\sphinxhyphen{}Claudel and others).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Most of the grammar is now presented using the notation mechanism
that has been used to present commands and tactics since Coq 8.8 and
which is documented in {\hyperref[\detokenize{language/core/basic:syntax-conventions}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax conventions}}}}
(\sphinxhref{https://github.com/coq/coq/pull/11183}{\#11183}%
\begin{footnote}[595]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11183}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11314}{\#11314}%
\begin{footnote}[596]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11314}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11423}{\#11423}%
\begin{footnote}[597]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11423}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11705}{\#11705}%
\begin{footnote}[598]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11705}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11718}{\#11718}%
\begin{footnote}[599]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11718}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11720}{\#11720}%
\begin{footnote}[600]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11720}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11961}{\#11961}%
\begin{footnote}[601]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11961}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/pull/12103}{\#12103}%
\begin{footnote}[602]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12103}
%
\end{footnote}, by Jim
Fehrle, reviewed by Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A glossary of terms and an index of attributes
(\sphinxhref{https://github.com/coq/coq/pull/11869}{\#11869}%
\begin{footnote}[603]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11869}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/12150}{\#12150}%
\begin{footnote}[604]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12150}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/pull/12224}{\#12224}%
\begin{footnote}[605]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12224}
%
\end{footnote},
by Jim Fehrle and Théo Zimmermann,
reviewed by Clément Pit\sphinxhyphen{}Claudel)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A selector that allows switching between versions of the reference
manual (\sphinxhref{https://github.com/coq/coq/pull/12286}{\#12286}%
\begin{footnote}[606]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12286}
%
\end{footnote}, by
Clément Pit\sphinxhyphen{}Claudel).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Most of the documented syntax has been thoroughly updated to make it
accurate and easily understood.  This was done using a
semi\sphinxhyphen{}automated \sphinxcode{\sphinxupquote{doc\_grammar}} tool introduced for this purpose and
through significant revisions to the text
(\sphinxhref{https://github.com/coq/coq/pull/9884}{\#9884}%
\begin{footnote}[607]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9884}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/10614}{\#10614}%
\begin{footnote}[608]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10614}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11314}{\#11314}%
\begin{footnote}[609]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11314}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11423}{\#11423}%
\begin{footnote}[610]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11423}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11705}{\#11705}%
\begin{footnote}[611]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11705}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11718}{\#11718}%
\begin{footnote}[612]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11718}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11720}{\#11720}%
\begin{footnote}[613]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11720}
%
\end{footnote}
\sphinxhref{https://github.com/coq/coq/pull/11797}{\#11797}%
\begin{footnote}[614]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11797}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11913}{\#11913}%
\begin{footnote}[615]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11913}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11958}{\#11958}%
\begin{footnote}[616]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11958}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11960}{\#11960}%
\begin{footnote}[617]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11960}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11961}{\#11961}%
\begin{footnote}[618]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11961}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/pull/12103}{\#12103}%
\begin{footnote}[619]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12103}
%
\end{footnote}, by Jim
Fehrle, reviewed by Théo Zimmermann and Jason Gross).

\end{itemize}


\subparagraph{Infrastructure and dependencies}
\label{\detokenize{changes:id595}}\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Minimal versions of dependencies for building the reference manual:
now requires Sphinx >= 2.3.1 \& < 3.0.0, sphinx\_rtd\_theme 0.4.3+ and
sphinxcontrib\sphinxhyphen{}bibtex 0.4.2+.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
The reference manual is known not to build properly with
Sphinx 3.
\end{sphinxadmonition}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/12224}{\#12224}%
\begin{footnote}[620]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12224}
%
\end{footnote},
by Jim Fehrle and Théo Zimmermann).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Python 2 is no longer required in any part of the codebase
(\sphinxhref{https://github.com/coq/coq/pull/11245}{\#11245}%
\begin{footnote}[621]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11245}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\end{itemize}


\paragraph{Changes in 8.12.0}
\label{\detokenize{changes:changes-in-8-12-0}}
\sphinxAtStartPar
\sphinxstylestrong{Notations}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Simultaneous definition of terms and notations now support custom entries.
Fixes \sphinxhref{https://github.com/coq/coq/pull/11121}{\#11121}%
\begin{footnote}[622]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11121}
%
\end{footnote}.
(\sphinxhref{https://github.com/coq/coq/pull/11523}{\#12523}%
\begin{footnote}[623]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11523}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Printing bug with notations for n\sphinxhyphen{}ary applications used with applied references.
(\sphinxhref{https://github.com/coq/coq/pull/12683}{\#12683}%
\begin{footnote}[624]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12683}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/pull/12682}{\#12682}%
\begin{footnote}[625]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12682}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactics}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
{\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}} (and discriminated hint bases) now correctly
classify local variables as being unfoldable
(\sphinxhref{https://github.com/coq/coq/pull/12572}{\#12572}%
\begin{footnote}[626]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12572}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12571}{\#12571}%
\begin{footnote}[627]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12571}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactic language}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Excluding occurrences was causing an anomaly in tactics
(e.g., \sphinxcode{\sphinxupquote{\DUrole{keyword}{pattern} \DUrole{operator}{\_} \DUrole{name}{at} \DUrole{name}{L}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{L}}} is \sphinxcode{\sphinxupquote{\DUrole{operator}{\sphinxhyphen{}}\DUrole{literal,number,integer}{2}}}).
(\sphinxhref{https://github.com/coq/coq/pull/12541}{\#12541}%
\begin{footnote}[628]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12541}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12228}{\#12228}%
\begin{footnote}[629]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12228}
%
\end{footnote},
by Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Parsing of multi\sphinxhyphen{}parameters Ltac2 types
(\sphinxhref{https://github.com/coq/coq/pull/12594}{\#12594}%
\begin{footnote}[630]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12594}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12595}{\#12595}%
\begin{footnote}[631]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12595}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{SSReflect}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Do not store the full environment inside ssr ast\_closure\_term
(\sphinxhref{https://github.com/coq/coq/pull/12708}{\#12708}%
\begin{footnote}[632]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12708}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12707}{\#12707}%
\begin{footnote}[633]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12707}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Commands and options}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Properly report the mismatched magic number of vo files
(\sphinxhref{https://github.com/coq/coq/pull/12677}{\#12677}%
\begin{footnote}[634]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12677}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12513}{\#12513}%
\begin{footnote}[635]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12513}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Arbitrary hints have been undeprecated, and their definition
now triggers a standard warning instead
(\sphinxhref{https://github.com/coq/coq/pull/12678}{\#12678}%
\begin{footnote}[636]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12678}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11970}{\#11970}%
\begin{footnote}[637]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11970}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{CoqIDE}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} CoqIDE no longer exits when trying to open a file whose name is not a valid identifier
(\sphinxhref{https://github.com/coq/coq/pull/12562}{\#12562}%
\begin{footnote}[638]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12562}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10988}{\#10988}%
\begin{footnote}[639]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10988}
%
\end{footnote},
by Vincent Laporte).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Infrastructure and dependencies}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Running \sphinxcode{\sphinxupquote{make}} in \sphinxcode{\sphinxupquote{test\sphinxhyphen{}suite/}} twice (or more) in a row will no longer
rebuild the \sphinxcode{\sphinxupquote{modules/}} tests on subsequent runs, if they have not been
modified in the meantime (\sphinxhref{https://github.com/coq/coq/pull/12583}{\#12583}%
\begin{footnote}[640]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12583}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12582}{\#12582}%
\begin{footnote}[641]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12582}
%
\end{footnote}, by Jason Gross).

\end{itemize}


\paragraph{Changes in 8.12.1}
\label{\detokenize{changes:changes-in-8-12-1}}
\sphinxAtStartPar
\sphinxstylestrong{Kernel}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} Incompleteness of conversion checking on problems
involving {\hyperref[\detokenize{language/core/conversion:eta-expansion-sect}]{\sphinxcrossref{\DUrole{std,std-ref}{η\sphinxhyphen{}expansion}}}} and {\hyperref[\detokenize{addendum/universe-polymorphism:cumulative}]{\sphinxcrossref{\DUrole{std,std-ref}{cumulative universe
polymorphic inductive types}}}} (\sphinxhref{https://github.com/coq/coq/pull/12738}{\#12738}%
\begin{footnote}[642]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12738}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/7015}{\#7015}%
\begin{footnote}[643]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7015}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Polymorphic side\sphinxhyphen{}effects inside monomorphic definitions were incorrectly
handled as not inlined. This allowed deriving an inconsistency
(\sphinxhref{https://github.com/coq/coq/pull/13331}{\#13331}%
\begin{footnote}[644]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13331}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13330}{\#13330}%
\begin{footnote}[645]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13330}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Notations}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Undetected collision between a lonely notation and a notation in
scope at printing time
(\sphinxhref{https://github.com/coq/coq/pull/12946}{\#12946}%
\begin{footnote}[646]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12946}
%
\end{footnote},
fixes the first part of \sphinxhref{https://github.com/coq/coq/issues/12908}{\#12908}%
\begin{footnote}[647]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12908}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Printing of notations in custom entries with
variables not mentioning an explicit level
(\sphinxhref{https://github.com/coq/coq/pull/13026}{\#13026}%
\begin{footnote}[648]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13026}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12775}{\#12775}%
\begin{footnote}[649]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12775}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/13018}{\#13018}%
\begin{footnote}[650]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13018}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactics}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}} and {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} support registration of a
\sphinxcode{\sphinxupquote{\DUrole{name}{core}\DUrole{operator}{.}\DUrole{name}{identity}}}\sphinxhyphen{}like equality in \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}, such as HoTT's \sphinxcode{\sphinxupquote{\DUrole{name}{path}}}
(\sphinxhref{https://github.com/coq/coq/pull/12847}{\#12847}%
\begin{footnote}[651]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12847}
%
\end{footnote},
partially fixes \sphinxhref{https://github.com/coq/coq/issues/12846}{\#12846}%
\begin{footnote}[652]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12846}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Anomaly with {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} involving artificial
dependencies disappearing by reduction
(\sphinxhref{https://github.com/coq/coq/pull/12816}{\#12816}%
\begin{footnote}[653]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12816}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12787}{\#12787}%
\begin{footnote}[654]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12787}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactic language}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Miscellaneous issues with locating tactic errors
(\sphinxhref{https://github.com/coq/coq/pull/13247}{\#13247}%
\begin{footnote}[655]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13247}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12773}{\#12773}%
\begin{footnote}[656]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12773}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/12992}{\#12992}%
\begin{footnote}[657]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12992}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{SSReflect}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Regression in error reporting after {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.case-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}}.
A generic error message "Could not fill dependent hole in apply" was
reported for any error following {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.case-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}} or
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.elim-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/12857}{\#12857}%
\begin{footnote}[658]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12857}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12837}{\#12837}%
\begin{footnote}[659]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12837}
%
\end{footnote},
by Enrico Tassi).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Commands and options}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Failures of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} in the presence of primitive projections
(\sphinxhref{https://github.com/coq/coq/pull/13301}{\#13301}%
\begin{footnote}[660]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13301}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13298}{\#13298}%
\begin{footnote}[661]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13298}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} supports filtering on parts of identifiers which are
not proper identifiers themselves, such as \sphinxcode{\sphinxupquote{\DUrole{notation}{"1"}}}
(\sphinxhref{https://github.com/coq/coq/pull/13351}{\#13351}%
\begin{footnote}[662]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13351}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13349}{\#13349}%
\begin{footnote}[663]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13349}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tools}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Special symbols now escaped in the index produced by coqdoc,
avoiding collision with the syntax of the output format
(\sphinxhref{https://github.com/coq/coq/pull/12754}{\#12754}%
\begin{footnote}[664]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12754}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12752}{\#12752}%
\begin{footnote}[665]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12752}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
The \sphinxcode{\sphinxupquote{details}} environment added in the 8.12 release can now be used
as advertised in the reference manual
(\sphinxhref{https://github.com/coq/coq/pull/12772}{\#12772}%
\begin{footnote}[666]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12772}
%
\end{footnote},
by Thomas Letan).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Targets such as \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed}} in \sphinxcode{\sphinxupquote{coq\_makefile}}\sphinxhyphen{}made
\sphinxcode{\sphinxupquote{Makefile}}s no longer error in rare cases where \sphinxcode{\sphinxupquote{\sphinxhyphen{}\sphinxhyphen{}output\sphinxhyphen{}sync}} is not
passed to make and the timing output gets interleaved in just the wrong way
(\sphinxhref{https://github.com/coq/coq/pull/13063}{\#13063}%
\begin{footnote}[667]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13063}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/13062}{\#13062}%
\begin{footnote}[668]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13062}
%
\end{footnote}, by Jason Gross).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{CoqIDE}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
View menu "Display parentheses"
(\sphinxhref{https://github.com/coq/coq/pull/12794}{\#12794}%
\begin{footnote}[669]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12794}
%
\end{footnote} and \sphinxhref{https://github.com/coq/coq/pull/13067}{\#13067}%
\begin{footnote}[670]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13067}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12793}{\#12793}%
\begin{footnote}[671]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12793}
%
\end{footnote},
by Jean\sphinxhyphen{}Christophe Léchenet and Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Infrastructure and dependencies}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Coq is now tested against OCaml 4.11.1
(\sphinxhref{https://github.com/coq/coq/pull/12972}{\#12972}%
\begin{footnote}[672]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12972}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
The reference manual can now build with Sphinx 3
(\sphinxhref{https://github.com/coq/coq/pull/13011}{\#13011}%
\begin{footnote}[673]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13011}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/12332}{\#12332}%
\begin{footnote}[674]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/12332}
%
\end{footnote},
by Théo Zimmermann and Jim Fehrle).

\end{itemize}


\paragraph{Changes in 8.12.2}
\label{\detokenize{changes:changes-in-8-12-2}}
\sphinxAtStartPar
\sphinxstylestrong{Notations}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
8.12 regression causing notations mentioning a coercion to be ignored
(\sphinxhref{https://github.com/coq/coq/pull/13436}{\#13436}%
\begin{footnote}[675]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13436}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13432}{\#13432}%
\begin{footnote}[676]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13432}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactics}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
8.12 regression: incomplete inference of implicit arguments in {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.exists}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exists}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/13468}{\#13468}%
\begin{footnote}[677]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/13468}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/13456}{\#13456}%
\begin{footnote}[678]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/13456}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}


\subsubsection{Version 8.11}
\label{\detokenize{changes:version-8-11}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id655}}
\sphinxAtStartPar
The main changes brought by Coq version 8.11 are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{changes:id695}]{\sphinxcrossref{\DUrole{std,std-ref}{Ltac2}}}}, a new tactic language for writing more robust larger scale
tactics, with built\sphinxhyphen{}in support for datatypes and the multi\sphinxhyphen{}goal tactic monad.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{changes:primitivefloats}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive floats}}}} are integrated in terms and follow the binary64 format
of the IEEE 754 standard, as specified in the \sphinxcode{\sphinxupquote{Coq.Float.Floats}} library.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{changes:sections}]{\sphinxcrossref{\DUrole{std,std-ref}{Cleanups}}}} of the section mechanism, delayed proofs and further
restrictions of template polymorphism to fix soundness issues related to
universes.

\item {} 
\sphinxAtStartPar
New {\hyperref[\detokenize{changes:unsafeflags}]{\sphinxcrossref{\DUrole{std,std-ref}{unsafe flags}}}} to disable locally guard, positivity and universe
checking. Reliance on these flags is always printed by
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Print} \DUrole{name}{Assumptions}}}.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{changes:exportbug}]{\sphinxcrossref{\DUrole{std,std-ref}{Fixed bugs}}}} of \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Export}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Import}}} that can have a
significant impact on user developments (\sphinxstylestrong{common source of
incompatibility!}).

\item {} 
\sphinxAtStartPar
New interactive development method based on \sphinxcode{\sphinxupquote{vos}} {\hyperref[\detokenize{changes:vos}]{\sphinxcrossref{\DUrole{std,std-ref}{interface files}}}},
allowing to work on a file without recompiling the proof parts of their
dependencies.

\item {} 
\sphinxAtStartPar
New \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Arguments}}} annotation for {\hyperref[\detokenize{changes:bidirarguments}]{\sphinxcrossref{\DUrole{std,std-ref}{bidirectional type inference}}}}
configuration for reference (e.g. constants, inductive) applications.

\item {} 
\sphinxAtStartPar
New {\hyperref[\detokenize{changes:refineinstance}]{\sphinxcrossref{\DUrole{std,std-ref}{refine attribute}}}} for {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} can be used instead of
the removed \sphinxcode{\sphinxupquote{Refine Instance Mode}}.

\item {} 
\sphinxAtStartPar
Generalization of the \sphinxcode{\sphinxupquote{\DUrole{name}{under}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{over}}} {\hyperref[\detokenize{changes:ssrunderover}]{\sphinxcrossref{\DUrole{std,std-ref}{tactics}}}} of SSReflect to
arbitrary relations.

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{changes:reals}]{\sphinxcrossref{\DUrole{std,std-ref}{Revision}}}} of the \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Reals}}} library, its axiomatisation and
instances of the constructive and classical real numbers.

\end{itemize}

\sphinxAtStartPar
Additionally, while the \sphinxcode{\sphinxupquote{omega}} tactic is not yet deprecated in
this version of Coq, it should soon be the case and we already
recommend users to switch to {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} in new proof scripts.

\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{dev/doc/critical\sphinxhyphen{}bugs}} file documents the known critical bugs
of Coq and affected releases. See the {\hyperref[\detokenize{changes:changes-in-8-11-beta1}]{\sphinxcrossref{Changes in 8.11+beta1}}}
section and following sections for the detailed list of changes,
including potentially breaking changes marked with \sphinxstylestrong{Changed}.

\sphinxAtStartPar
Coq's documentation is available at \sphinxurl{https://coq.github.io/doc/v8.11/api} (documentation of
the ML API), \sphinxurl{https://coq.github.io/doc/v8.11/refman} (reference
manual), and \sphinxurl{https://coq.github.io/doc/v8.11/stdlib} (documentation of
the standard library).

\sphinxAtStartPar
Maxime Dénès, Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop and Théo Zimmermann worked on maintaining and improving the
continuous integration system and package building infrastructure.

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

\sphinxAtStartPar
The 61 contributors to this version are Michael D. Adams, Guillaume
Allais, Helge Bahmann, Langston Barrett, Guillaume Bertholon, Frédéric
Besson, Simon Boulier, Michele Caci, Tej Chajed, Arthur Charguéraud,
Cyril Cohen, Frédéric Dabrowski, Arthur Azevedo de Amorim, Maxime
Dénès, Nikita Eshkeev, Jim Fehrle, Emilio Jesús Gallego Arias,
Paolo G. Giarrusso, Gaëtan Gilbert, Georges Gonthier, Jason Gross,
Samuel Gruetter, Armaël Guéneau, Hugo Herbelin, Florent Hivert, Jasper
Hugunin, Shachar Itzhaky, Jan\sphinxhyphen{}Oliver Kaiser, Robbert Krebbers, Vincent
Laporte, Olivier Laurent, Samuel Lelièvre, Nicholas Lewycky, Yishuai
Li, Jose Fernando Lopez Fernandez, Andreas Lynge, Kenji Maillard, Erik
Martin\sphinxhyphen{}Dorel, Guillaume Melquiond, Alexandre Moine, Oliver Nash,
Wojciech Nawrocki, Antonio Nikishaev, Pierre\sphinxhyphen{}Marie Pédrot, Clément
Pit\sphinxhyphen{}Claudel, Lars Rasmusson, Robert Rand, Talia Ringer, JP Rodi,
Pierre Roux, Kazuhiko Sakaguchi, Vincent Semeria, Michael Soegtrop,
Matthieu Sozeau, spanjel, Claude Stolze, Enrico Tassi, Laurent Théry,
James R. Wilcox, Xia Li\sphinxhyphen{}yao, Théo Zimmermann

\sphinxAtStartPar
Many power users helped to improve the design of the new features via
the issue and pull request system, the Coq development mailing list,
the \sphinxhref{mailto:coq-club@inria.fr}{coq\sphinxhyphen{}club@inria.fr} mailing list or the \sphinxhref{https://coq.discourse.group/}{Discourse forum}%
\begin{footnote}[679]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.discourse.group/}
%
\end{footnote}. It would be impossible to mention
exhaustively the names of everybody who to some extent influenced the
development.

\sphinxAtStartPar
Version 8.11 is the sixth release of Coq developed on a time\sphinxhyphen{}based
development cycle. Its development spanned 3 months from the release of
Coq 8.10. Pierre\sphinxhyphen{}Marie Pédrot is the release manager and maintainer of this
release, assisted by Matthieu Sozeau. This release is the result of 2000+
commits and 300+ PRs merged, closing 75+ issues.

\begin{DUlineblock}{0em}
\item[] Paris, November 2019,
\item[] Matthieu Sozeau for the Coq development team
\item[] 
\end{DUlineblock}


\paragraph{Changes in 8.11+beta1}
\label{\detokenize{changes:changes-in-8-11-beta1}}
\sphinxAtStartPar
\sphinxstylestrong{Kernel}
\begin{quote}
\phantomsection\label{\detokenize{changes:primitivefloats}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A built\sphinxhyphen{}in support of floating\sphinxhyphen{}point arithmetic, allowing
one to devise efficient reflection tactics involving numerical
computation. Primitive floats are added in the language of terms,
following the binary64 format of the IEEE 754 standard, and the
related operations are implemented for the different reduction
engines of Coq by using the corresponding processor operators in
rounding\sphinxhyphen{}to\sphinxhyphen{}nearest\sphinxhyphen{}even. The properties of these operators are
axiomatized in the theory \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Floats}\DUrole{operator}{.}\DUrole{name}{FloatAxioms}}} which is part
of the library \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Floats}\DUrole{operator}{.}\DUrole{name}{Floats}}}.
See Section {\hyperref[\detokenize{language/core/primitive:primitive-floats}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Floats}}}}
(\sphinxhref{https://github.com/coq/coq/pull/9867}{\#9867}%
\begin{footnote}[680]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9867}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/8276}{\#8276}%
\begin{footnote}[681]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/8276}
%
\end{footnote},
by Guillaume Bertholon, Erik Martin\sphinxhyphen{}Dorel, Pierre Roux).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Internal definitions generated by {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.abstract}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{abstract}}}}}\sphinxhyphen{}like tactics are now inlined
inside universe {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}\sphinxhyphen{}terminated polymorphic definitions, similarly to what
happens for their monomorphic counterparts,
(\sphinxhref{https://github.com/coq/coq/pull/10439}{\#10439}%
\begin{footnote}[682]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10439}
%
\end{footnote}, by Pierre\sphinxhyphen{}Marie Pédrot).

\phantomsection\label{\detokenize{changes:sections}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Section data is now part of the kernel. Solves a soundness issue
in interactive mode where global monomorphic universe constraints would be
dropped when forcing a delayed opaque proof inside a polymorphic section. Also
relaxes the nesting criterion for sections, as polymorphic sections can now
appear inside a monomorphic one
(\sphinxhref{https://github.com/coq/coq/pull/10664}{\#10664}%
\begin{footnote}[683]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10664}
%
\end{footnote}, by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Using \sphinxcode{\sphinxupquote{SProp}} is now allowed by default, without needing to pass
\sphinxcode{\sphinxupquote{\sphinxhyphen{}allow\sphinxhyphen{}sprop}} or use {\hyperref[\detokenize{addendum/sprop:coq:flag.Allow-StrictProp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Allow StrictProp}}}}} (\sphinxhref{https://github.com/coq/coq/pull/10811}{\#10811}%
\begin{footnote}[684]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10811}
%
\end{footnote}, by Gaëtan Gilbert).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Specification language, type inference}
\begin{quote}
\phantomsection\label{\detokenize{changes:bidirarguments}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Annotation in \sphinxcode{\sphinxupquote{Arguments}} for bidirectionality hints: it is now possible
to tell type inference to use type information from the context once the \sphinxcode{\sphinxupquote{n}}
first arguments of an application are known. The syntax is:
\sphinxcode{\sphinxupquote{Arguments foo x y \& z}}. See {\hyperref[\detokenize{language/extensions/arguments-command:bidirectionality-hints}]{\sphinxcrossref{\DUrole{std,std-ref}{Bidirectionality hints}}}}
(\sphinxhref{https://github.com/coq/coq/pull/10049}{\#10049}%
\begin{footnote}[685]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10049}
%
\end{footnote}, by Maxime Dénès with
help from Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Record fields can be annotated to prevent them from being used as canonical projections;
see {\hyperref[\detokenize{language/extensions/canonical:canonicalstructures}]{\sphinxcrossref{\DUrole{std,std-ref}{Canonical Structures}}}} for details
(\sphinxhref{https://github.com/coq/coq/pull/10076}{\#10076}%
\begin{footnote}[686]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10076}
%
\end{footnote},
by Vincent Laporte).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Require parentheses around nested disjunctive patterns, so that pattern and
term syntax are consistent; match branch patterns no longer require
parentheses for notation at level 100 or more.

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
Incompatibilities
\begin{itemize}
\item {} 
\sphinxAtStartPar
In \sphinxcode{\sphinxupquote{\DUrole{keyword}{match} \DUrole{name}{p} \DUrole{keyword}{with} \DUrole{operator}{(\_,} \DUrole{operator}{(}\DUrole{literal,number,integer}{0}\DUrole{operator}{|}\DUrole{literal,number,integer}{1}\DUrole{operator}{))} \DUrole{operator}{=>} \DUrole{operator}{...}}} parentheses may no longer be
omitted around \sphinxcode{\sphinxupquote{\DUrole{notation}{0|1}}}.

\item {} 
\sphinxAtStartPar
Notation \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{p} \DUrole{operator}{|} \DUrole{name}{q}\DUrole{operator}{)}}} now potentially clashes with core pattern syntax,
and should be avoided. \sphinxcode{\sphinxupquote{\sphinxhyphen{}w disj\sphinxhyphen{}pattern\sphinxhyphen{}notation}} flags such {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}}.

\end{itemize}
\end{sphinxadmonition}

\sphinxAtStartPar
See {\hyperref[\detokenize{language/extensions/match:extendedpatternmatching}]{\sphinxcrossref{\DUrole{std,std-ref}{Extended pattern matching}}}} for details
(\sphinxhref{https://github.com/coq/coq/pull/10167}{\#10167}%
\begin{footnote}[687]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10167}
%
\end{footnote},
by Georges Gonthier).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
{\hyperref[\detokenize{using/libraries/funind:coq:cmd.Function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} always opens a proof when used with a \sphinxcode{\sphinxupquote{measure}} or \sphinxcode{\sphinxupquote{wf}}
annotation, see {\hyperref[\detokenize{using/libraries/funind:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}} for the updated
documentation (\sphinxhref{https://github.com/coq/coq/pull/10215}{\#10215}%
\begin{footnote}[688]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10215}
%
\end{footnote},
by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The legacy command {\hyperref[\detokenize{addendum/generalized-rewriting:coq:cmd.Add-Morphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add Morphism}}}}} always opens a proof and cannot be used
inside a module type. In order to declare a module type parameter that
happens to be a morphism, use {\hyperref[\detokenize{addendum/generalized-rewriting:coq:cmd.Declare-Morphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare Morphism}}}}}. See
{\hyperref[\detokenize{addendum/generalized-rewriting:deprecated-syntax-for-generalized-rewriting}]{\sphinxcrossref{\DUrole{std,std-ref}{Deprecated syntax and backward incompatibilities}}}} for the updated
documentation (\sphinxhref{https://github.com/coq/coq/pull/10215}{\#10215}%
\begin{footnote}[689]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10215}
%
\end{footnote},
by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The universe polymorphism setting now applies from the opening of a section.
In particular, it is not possible anymore to mix polymorphic and monomorphic
definitions in a section when there are no variables nor universe constraints
defined in this section. This makes the behaviour consistent with the
documentation. (\sphinxhref{https://github.com/coq/coq/pull/10441}{\#10441}%
\begin{footnote}[690]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10441}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{language/core/sections:coq:cmd.Section}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Section}}}}} command now accepts the "universes" attribute. In
addition to setting the section universe polymorphism, it also locally sets
the universe polymorphic option inside the section.
(\sphinxhref{https://github.com/coq/coq/pull/10441}{\#10441}%
\begin{footnote}[691]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10441}
%
\end{footnote}, by Pierre\sphinxhyphen{}Marie Pédrot)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
\sphinxcode{\sphinxupquote{Program Fixpoint}} now uses \sphinxcode{\sphinxupquote{ex}} and \sphinxcode{\sphinxupquote{sig}} to make telescopes
involving \sphinxcode{\sphinxupquote{Prop}} types (\sphinxhref{https://github.com/coq/coq/pull/10758}{\#10758}%
\begin{footnote}[692]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10758}
%
\end{footnote}, by Gaëtan Gilbert, fixing
\sphinxhref{https://github.com/coq/coq/issues/10757}{\#10757}%
\begin{footnote}[693]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10757}
%
\end{footnote} reported by
Xavier Leroy).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Output of the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Print}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.About}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{About}}}}} commands.
Arguments meta\sphinxhyphen{}data is now displayed as the corresponding
{\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} command instead of the
human\sphinxhyphen{}targeted prose used in previous Coq versions. (\sphinxhref{https://github.com/coq/coq/pull/10985}{\#10985}%
\begin{footnote}[694]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10985}
%
\end{footnote}, by Gaëtan Gilbert).

\phantomsection\label{\detokenize{changes:refineinstance}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:} {\hyperref[\detokenize{addendum/type-classes:coq:attr.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} attribute for {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}}, a more
predictable version of the old \sphinxcode{\sphinxupquote{Refine Instance Mode}} which
unconditionally opens a proof (\sphinxhref{https://github.com/coq/coq/pull/10996}{\#10996}%
\begin{footnote}[695]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10996}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The unsupported attribute error is now an error\sphinxhyphen{}by\sphinxhyphen{}default warning,
meaning it can be disabled (\sphinxhref{https://github.com/coq/coq/pull/10997}{\#10997}%
\begin{footnote}[696]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10997}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} Bugs sometimes preventing to define valid (co)fixpoints with implicit arguments
in the presence of local definitions, see \sphinxhref{https://github.com/coq/coq/issues/3282}{\#3282}%
\begin{footnote}[697]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/3282}
%
\end{footnote}
(\sphinxhref{https://github.com/coq/coq/pull/11132}{\#11132}%
\begin{footnote}[698]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11132}
%
\end{footnote}, by Hugo Herbelin).

\begin{sphinxadmonition}{note}{Example}

\sphinxAtStartPar
The following features an implicit argument after a local
definition. It was wrongly rejected.

\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{f} \PYG{o}{:=} \PYG{k}{fix} \PYG{n}{f} \PYG{o}{(}\PYG{n}{o} \PYG{o}{:=} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{n}{n} \PYG{o}{:} \PYG{n}{nat}\PYG{o}{\PYGZcb{}} \PYG{n}{m} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{m} \PYG{k}{with} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{|} \PYG{n}{S} \PYG{n}{m\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{f} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:=}\PYG{n}{n}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)} \PYG{n}{m\PYGZsq{}} \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Notations}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Numeral Notations now support sorts in the input to printing
functions (e.g., numeral notations can be defined for terms
containing things like \sphinxcode{\sphinxupquote{@cons Set nat nil}}).  (\sphinxhref{https://github.com/coq/coq/pull/9883}{\#9883}%
\begin{footnote}[699]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9883}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\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}}}}} commands now support the \sphinxcode{\sphinxupquote{deprecated}}
attribute
(\sphinxhref{https://github.com/coq/coq/pull/10180}{\#10180}%
\begin{footnote}[700]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10180}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
The former \sphinxcode{\sphinxupquote{compat}} annotation for notations is
deprecated, and its semantics changed. It is now made equivalent to using
a \sphinxcode{\sphinxupquote{deprecated}} attribute, and is no longer connected with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}compat}}
command\sphinxhyphen{}line flag
(\sphinxhref{https://github.com/coq/coq/pull/10180}{\#10180}%
\begin{footnote}[701]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10180}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
A simplification of parsing rules could cause a slight change of
parsing precedences for the very rare users who defined notations
with \sphinxcode{\sphinxupquote{constr}} at level strictly between 100 and 200 and used these
notations on the right\sphinxhyphen{}hand side of a cast operator (\sphinxcode{\sphinxupquote{:}}, \sphinxcode{\sphinxupquote{<:}},
\sphinxcode{\sphinxupquote{<<:}}) (\sphinxhref{https://github.com/coq/coq/pull/10963}{\#10963}%
\begin{footnote}[702]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10963}
%
\end{footnote}, by Théo
Zimmermann, simplification initially noticed by Jim Fehrle).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactics}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as {[}= \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-intropattern}]{\sphinxcrossref{\DUrole{hole}{intropattern}}}}}\DUrole{notation-sup}{+}} {]}}}} as
an alternative to \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-simple_intropattern}]{\sphinxcrossref{\DUrole{hole}{simple\_intropattern}}}}}\DUrole{notation-sup}{+}}}}} using
the standard \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-injection_intropattern}]{\sphinxcrossref{\DUrole{hole}{injection\_intropattern}}}}}}} syntax (\sphinxhref{https://github.com/coq/coq/pull/9288}{\#9288}%
\begin{footnote}[703]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9288}
%
\end{footnote}, by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Reimplementation of the {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} tactic. The tactic is more efficient and copes with dependent hypotheses.
It can also be extended by redefining the tactic \sphinxcode{\sphinxupquote{zify\_post\_hook}}.
(\sphinxhref{https://github.com/coq/coq/pull/9856}{\#9856}%
\begin{footnote}[704]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9856}
%
\end{footnote}, fixes
\sphinxhref{https://github.com/coq/coq/issues/8898}{\#8898}%
\begin{footnote}[705]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/8898}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/issues/7886}{\#7886}%
\begin{footnote}[706]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7886}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/issues/9848}{\#9848}%
\begin{footnote}[707]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9848}
%
\end{footnote} and
\sphinxhref{https://github.com/coq/coq/issues/5155}{\#5155}%
\begin{footnote}[708]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/5155}
%
\end{footnote}, by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The goal selector tactical \sphinxcode{\sphinxupquote{only}} now checks that the goal range
it is given is valid instead of ignoring goals out of the focus
range (\sphinxhref{https://github.com/coq/coq/pull/10318}{\#10318}%
\begin{footnote}[709]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10318}
%
\end{footnote}, by Gaëtan
Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Flags {\hyperref[\detokenize{addendum/micromega:coq:flag.Lia-Cache}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Lia Cache}}}}}, {\hyperref[\detokenize{addendum/micromega:coq:flag.Nia-Cache}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Nia Cache}}}}} and {\hyperref[\detokenize{addendum/micromega:coq:flag.Nra-Cache}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Nra Cache}}}}}.
(\sphinxhref{https://github.com/coq/coq/pull/10765}{\#10765}%
\begin{footnote}[710]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10765}
%
\end{footnote}, by Frédéric Besson,
see \sphinxhref{https://github.com/coq/coq/issues/10772}{\#10772}%
\begin{footnote}[711]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10772}
%
\end{footnote} for use case).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
The {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} tactic is now aware of \sphinxcode{\sphinxupquote{Z.to\_N}}.
(\sphinxhref{https://github.com/coq/coq/pull/10774}{\#10774}%
\begin{footnote}[712]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10774}
%
\end{footnote}, grants
\sphinxhref{https://github.com/coq/coq/issues/9162}{\#9162}%
\begin{footnote}[713]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9162}
%
\end{footnote}, by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_succeeds}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_succeeds}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_fails}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_fails}}}}} tactics now
only run their tactic argument once, even if it has multiple
successes.  This prevents blow\sphinxhyphen{}up and looping from using
multisuccess tactics with {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_succeeds}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_succeeds}}}}}.  (\sphinxhref{https://github.com/coq/coq/pull/10966}{\#10966}%
\begin{footnote}[714]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10966}
%
\end{footnote} fixes \sphinxhref{https://github.com/coq/coq/issues/10965}{\#10965}%
\begin{footnote}[715]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10965}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
The {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_succeeds}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_succeeds}}}}} and {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.assert_fails}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assert\_fails}}}}} tactics now
behave correctly when their tactic fully solves the goal.  (\sphinxhref{https://github.com/coq/coq/pull/10966}{\#10966}%
\begin{footnote}[716]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10966}
%
\end{footnote} fixes \sphinxhref{https://github.com/coq/coq/issues/9114}{\#9114}%
\begin{footnote}[717]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9114}
%
\end{footnote}, by Jason Gross).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactic language}
\begin{quote}
\phantomsection\label{\detokenize{changes:id695}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Ltac2, a new version of the tactic language Ltac, that doesn't
preserve backward compatibility, has been integrated in the main Coq
distribution.  It is still experimental, but we already recommend
users of advanced Ltac to start using it and report bugs or request
enhancements.  See its documentation in the {\hyperref[\detokenize{proof-engine/ltac2:ltac2}]{\sphinxcrossref{\DUrole{std,std-ref}{dedicated chapter}}}} (\sphinxhref{https://github.com/coq/coq/pull/10002}{\#10002}%
\begin{footnote}[718]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10002}
%
\end{footnote}, plugin
authored by Pierre\sphinxhyphen{}Marie Pédrot, with contributions by various
users, integration by Maxime Dénès, help on integrating / improving
the documentation by Théo Zimmermann and Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Ltac2 tactic notations with “constr” arguments can specify the
notation scope for these arguments;
see {\hyperref[\detokenize{proof-engine/ltac2:ltac2-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Notations}}}} for details
(\sphinxhref{https://github.com/coq/coq/pull/10289}{\#10289}%
\begin{footnote}[719]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10289}
%
\end{footnote},
by Vincent Laporte).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
White spaces are forbidden in the \sphinxcode{\sphinxupquote{\DUrole{notation}{\&{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} syntax for ltac2 references
that are described in {\hyperref[\detokenize{proof-engine/ltac2:ltac2-built-in-quotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Built\sphinxhyphen{}in quotations}}}}
(\sphinxhref{https://github.com/coq/coq/pull/10324}{\#10324}%
\begin{footnote}[720]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10324}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10088}{\#10088}%
\begin{footnote}[721]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10088}
%
\end{footnote},
authored by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{SSReflect}
\begin{quote}
\phantomsection\label{\detokenize{changes:ssrunderover}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Generalize tactics {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} and {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.over}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{over}}}}} for any registered
relation. More precisely, assume the given context lemma has type
\sphinxcode{\sphinxupquote{forall f1 f2, .. \sphinxhyphen{}> (forall i, R1 (f1 i) (f2 i)) \sphinxhyphen{}> R2 f1 f2}}.  The
first step performed by {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} (since Coq 8.10) amounts to
calling the tactic {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.rewrite-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}, which
itself relies on {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.setoid_rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} if need be. So this step was
already compatible with a double implication or setoid equality for
the conclusion head symbol \sphinxcode{\sphinxupquote{R2}}. But a further step consists in
tagging the generated subgoal \sphinxcode{\sphinxupquote{R1 (f1 i) (?f2 i)}} to protect it from
unwanted evar instantiation, and get \sphinxcode{\sphinxupquote{Under\_rel \_ R1 (f1 i) (?f2 i)}}
that is displayed as \sphinxcode{\sphinxupquote{'Under{[} f1 i {]}}}. In Coq 8.10, this second
(convenience) step was only performed when \sphinxcode{\sphinxupquote{R1}} was Leibniz' \sphinxcode{\sphinxupquote{eq}} or
\sphinxcode{\sphinxupquote{iff}}. Now, it is also performed for any relation \sphinxcode{\sphinxupquote{R1}} which has a
\sphinxcode{\sphinxupquote{RewriteRelation}} instance (a \sphinxcode{\sphinxupquote{RelationClasses.Reflexive}} instance
being also needed so {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.over}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{over}}}}} can discharge the \sphinxcode{\sphinxupquote{'Under{[} \_ {]}}}
goal by instantiating the hidden evar.)
This feature generalizing support for setoid\sphinxhyphen{}like relations is
enabled as soon as we do both \sphinxcode{\sphinxupquote{Require Import ssreflect.}} and
\sphinxcode{\sphinxupquote{Require Setoid.}} Finally, a rewrite rule \sphinxcode{\sphinxupquote{UnderE}} has been
added if one wants to "unprotect" the evar, and instantiate it
manually with another rule than reflexivity (i.e., without using the
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.over}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{over}}}}} tactic nor the \sphinxcode{\sphinxupquote{over}} rewrite rule). See also Section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:under-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting under binders}}}} (\sphinxhref{https://github.com/coq/coq/pull/10022}{\#10022}%
\begin{footnote}[722]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10022}
%
\end{footnote},
by Erik Martin\sphinxhyphen{}Dorel, with suggestions and review by Enrico Tassi
and Cyril Cohen).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
A \sphinxcode{\sphinxupquote{\DUrole{name}{void}}} notation for the standard library empty type (\sphinxcode{\sphinxupquote{\DUrole{name}{Empty\_set}}})
(\sphinxhref{https://github.com/coq/coq/pull/10932}{\#10932}%
\begin{footnote}[723]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10932}
%
\end{footnote}, by Arthur Azevedo de
Amorim).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:} Lemma \sphinxcode{\sphinxupquote{\DUrole{name}{inj\_compr}}} to \sphinxcode{\sphinxupquote{\DUrole{name}{ssr}\DUrole{operator}{.}\DUrole{name}{ssrfun}}}
(\sphinxhref{https://github.com/coq/coq/pull/11136}{\#11136}%
\begin{footnote}[724]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11136}
%
\end{footnote}, by Cyril Cohen).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Commands and options}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Deprecated flag \sphinxcode{\sphinxupquote{Refine Instance Mode}}
(\sphinxhref{https://github.com/coq/coq/pull/9530}{\#9530}%
\begin{footnote}[725]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9530}
%
\end{footnote}, fixes
\sphinxhref{https://github.com/coq/coq/issues/3632}{\#3632}%
\begin{footnote}[726]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/3632}
%
\end{footnote}, \sphinxhref{https://github.com/coq/coq/issues/3890}{\#3890}%
\begin{footnote}[727]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/3890}
%
\end{footnote} and \sphinxhref{https://github.com/coq/coq/issues/4638}{\#4638}%
\begin{footnote}[728]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4638}
%
\end{footnote}
by Maxime Dénès, review by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Fail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fail}}}}} does not catch critical errors (including "stack overflow")
anymore (\sphinxhref{https://github.com/coq/coq/pull/10173}{\#10173}%
\begin{footnote}[729]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10173}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Undocumented \sphinxcode{\sphinxupquote{\DUrole{notation}{Instance : !{\hyperref[\detokenize{language/core/basic:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} syntax
(\sphinxhref{https://github.com/coq/coq/pull/10185}{\#10185}%
\begin{footnote}[730]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10185}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Deprecated \sphinxcode{\sphinxupquote{Show Script}} command
(\sphinxhref{https://github.com/coq/coq/pull/10277}{\#10277}%
\begin{footnote}[731]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10277}
%
\end{footnote}, by Gaëtan Gilbert).

\phantomsection\label{\detokenize{changes:unsafeflags}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Unsafe commands to enable/disable guard checking, positivity checking
and universes checking (providing a local \sphinxcode{\sphinxupquote{\sphinxhyphen{}type\sphinxhyphen{}in\sphinxhyphen{}type}}).
See {\hyperref[\detokenize{proof-engine/vernacular-commands:controlling-typing-flags}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling Typing Flags}}}}
(\sphinxhref{https://github.com/coq/coq/pull/10291}{\#10291}%
\begin{footnote}[732]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10291}
%
\end{footnote} by Simon Boulier).

\phantomsection\label{\detokenize{changes:exportbug}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Two bugs in {\hyperref[\detokenize{language/core/modules:coq:cmd.Export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Export}}}}}. This can have an impact on the behavior of the
{\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} command on libraries. \sphinxcode{\sphinxupquote{Import A}} when \sphinxcode{\sphinxupquote{A}} imports \sphinxcode{\sphinxupquote{B}} which exports
\sphinxcode{\sphinxupquote{C}} was importing \sphinxcode{\sphinxupquote{C}}, whereas {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} is not transitive. Also, after
\sphinxcode{\sphinxupquote{Import A B}}, the import of \sphinxcode{\sphinxupquote{B}} was sometimes incomplete
(\sphinxhref{https://github.com/coq/coq/pull/10476}{\#10476}%
\begin{footnote}[733]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10476}
%
\end{footnote}, by Maxime Dénès).

\begin{sphinxadmonition}{warning}{Warning:}
\sphinxAtStartPar
This is a common source of incompatibilities in projects
migrating to Coq 8.11.
\end{sphinxadmonition}

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Output generated by {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Printing-Dependent-Evars-Line}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Dependent Evars Line}}}}} flag
used by the Prooftree tool in Proof General.
(\sphinxhref{https://github.com/coq/coq/pull/10489}{\#10489}%
\begin{footnote}[734]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10489}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/4504}{\#4504}%
\begin{footnote}[735]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4504}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/issues/10399}{\#10399}%
\begin{footnote}[736]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10399}
%
\end{footnote} and
\sphinxhref{https://github.com/coq/coq/issues/10400}{\#10400}%
\begin{footnote}[737]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10400}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Optionally highlight the differences between successive proof steps in the
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:cmd.Show-Proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Proof}}}}} command.  Experimental; only available in coqtop
and Proof General for now, may be supported in other IDEs
in the future.
(\sphinxhref{https://github.com/coq/coq/pull/10494}{\#10494}%
\begin{footnote}[738]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10494}
%
\end{footnote},
by Jim Fehrle).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} Legacy commands \sphinxcode{\sphinxupquote{AddPath}}, \sphinxcode{\sphinxupquote{AddRecPath}}, and \sphinxcode{\sphinxupquote{DelPath}}
which were undocumented, broken variants of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Add-LoadPath}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add LoadPath}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Add-Rec-LoadPath}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add Rec LoadPath}}}}}, and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Remove-LoadPath}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove LoadPath}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/11187}{\#11187}%
\begin{footnote}[739]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11187}
%
\end{footnote},
by Maxime Dénès and Théo Zimmermann).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tools}
\begin{quote}
\phantomsection\label{\detokenize{changes:vos}}\end{quote}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
\sphinxcode{\sphinxupquote{coqc}} now provides the ability to generate compiled interfaces.
Use \sphinxcode{\sphinxupquote{coqc \sphinxhyphen{}vos foo.v}} to skip all opaque proofs during the
compilation of \sphinxcode{\sphinxupquote{foo.v}}, and output a file called \sphinxcode{\sphinxupquote{foo.vos}}.
This feature is experimental. It enables working on a Coq file without the need to
first compile the proofs contained in its dependencies
(\sphinxhref{https://github.com/coq/coq/pull/8642}{\#8642}%
\begin{footnote}[740]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8642}
%
\end{footnote} by Arthur Charguéraud, review by
Maxime Dénès and Emilio Gallego).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Command\sphinxhyphen{}line options \sphinxcode{\sphinxupquote{\sphinxhyphen{}require\sphinxhyphen{}import}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}require\sphinxhyphen{}export}},
\sphinxcode{\sphinxupquote{\sphinxhyphen{}require\sphinxhyphen{}import\sphinxhyphen{}from}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}require\sphinxhyphen{}export\sphinxhyphen{}from}}, as well as their
shorthand, \sphinxcode{\sphinxupquote{\sphinxhyphen{}ri}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}re}}, \sphinxcode{\sphinxupquote{\sphinxhyphen{}refrom}} and \sphinxhyphen{}\sphinxcode{\sphinxupquote{rifrom}}. Deprecate
confusing command line option \sphinxcode{\sphinxupquote{\sphinxhyphen{}require}}
(\sphinxhref{https://github.com/coq/coq/pull/10245}{\#10245}%
\begin{footnote}[741]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10245}
%
\end{footnote}
by Hugo Herbelin, review by Emilio Gallego).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Renamed \sphinxcode{\sphinxupquote{VDFILE}} from \sphinxcode{\sphinxupquote{.coqdeps.d}} to \sphinxcode{\sphinxupquote{.<CoqMakefile>.d}} in the \sphinxcode{\sphinxupquote{coq\_makefile}}
utility, where \sphinxcode{\sphinxupquote{<CoqMakefile>}} is the name of the output file given by the
\sphinxcode{\sphinxupquote{\sphinxhyphen{}o}} option. In this way two generated makefiles can coexist in the same
directory.
(\sphinxhref{https://github.com/coq/coq/pull/10947}{\#10947}%
\begin{footnote}[742]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10947}
%
\end{footnote}, by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} \sphinxcode{\sphinxupquote{coq\_makefile}} now supports environment variable \sphinxcode{\sphinxupquote{COQBIN}} with
no ending \sphinxcode{\sphinxupquote{/}} character (\sphinxhref{https://github.com/coq/coq/pull/11068}{\#11068}%
\begin{footnote}[743]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11068}
%
\end{footnote}, by Gaëtan Gilbert).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Standard library}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Moved the {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} hints of the \sphinxcode{\sphinxupquote{OrderedType}} module into a new \sphinxcode{\sphinxupquote{ordered\_type}}
database
(\sphinxhref{https://github.com/coq/coq/pull/9772}{\#9772}%
\begin{footnote}[744]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9772}
%
\end{footnote},
by Vincent Laporte).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:}
Deprecated modules \sphinxcode{\sphinxupquote{Coq.ZArith.Zlogarithm}} and \sphinxcode{\sphinxupquote{Coq.ZArith.Zsqrt\_compat}}
(\sphinxhref{https://github.com/coq/coq/pull/9811}{\#9811}%
\begin{footnote}[745]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9811}
%
\end{footnote},
by Vincent Laporte).

\phantomsection\label{\detokenize{changes:reals}}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Module \sphinxcode{\sphinxupquote{Reals.Cauchy.ConstructiveCauchyReals}} defines constructive real numbers
by Cauchy sequences of rational numbers
(\sphinxhref{https://github.com/coq/coq/pull/10445}{\#10445}%
\begin{footnote}[746]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10445}
%
\end{footnote}, by Vincent Semeria,
with the help and review of Guillaume Melquiond and Bas Spitters).
This module is not meant to be imported directly, please import
\sphinxcode{\sphinxupquote{Reals.Abstract.ConstructiveReals}} instead.

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
New module \sphinxcode{\sphinxupquote{Reals.ClassicalDedekindReals}} defines Dedekind real
numbers as boolean\sphinxhyphen{}valued functions along with 3 logical axioms:
limited principle of omniscience, excluded middle of negations, and
functional extensionality.  The exposed type \sphinxcode{\sphinxupquote{\DUrole{name}{R}}} in module
\sphinxcode{\sphinxupquote{\DUrole{name}{Reals}\DUrole{operator}{.}\DUrole{name}{Rdefinitions}}} now corresponds to these Dedekind reals,
hidden behind an opaque module, which significantly reduces the
number of axioms needed (see \sphinxcode{\sphinxupquote{Reals.Rdefinitions}} and
\sphinxcode{\sphinxupquote{Reals.Raxioms}}), while preserving backward compatibility.
Classical Dedekind reals are a quotient of constructive reals, which
allows to transport many constructive proofs to the classical case
(\sphinxhref{https://github.com/coq/coq/pull/10827}{\#10827}%
\begin{footnote}[747]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10827}
%
\end{footnote}, by Vincent Semeria,
based on discussions with Guillaume Melquiond, Bas Spitters and Hugo Herbelin,
code review by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
New lemmas on \sphinxcode{\sphinxupquote{\DUrole{name}{combine}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{filter}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{nodup}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{nth}}}, and
\sphinxcode{\sphinxupquote{\DUrole{name}{nth\_error}}} functions on lists
(\sphinxhref{https://github.com/coq/coq/pull/10651}{\#10651}%
\begin{footnote}[748]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10651}
%
\end{footnote}, and
\sphinxhref{https://github.com/coq/coq/pull/10731}{\#10731}%
\begin{footnote}[749]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10731}
%
\end{footnote}, by Oliver Nash).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The lemma \sphinxcode{\sphinxupquote{\DUrole{name}{filter\_app}}} was moved to the \sphinxcode{\sphinxupquote{\DUrole{name}{List}}} module
(\sphinxhref{https://github.com/coq/coq/pull/10651}{\#10651}%
\begin{footnote}[750]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10651}
%
\end{footnote}, by Oliver Nash).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Standard equivalence between weak excluded\sphinxhyphen{}middle and the
classical instance of De Morgan's law, in module \sphinxcode{\sphinxupquote{\DUrole{name}{ClassicalFacts}}}
(\sphinxhref{https://github.com/coq/coq/pull/10895}{\#10895}%
\begin{footnote}[751]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10895}
%
\end{footnote}, by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Infrastructure and dependencies}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Coq now officially supports OCaml 4.08.
See \sphinxcode{\sphinxupquote{INSTALL}} file for details
(\sphinxhref{https://github.com/coq/coq/pull/10471}{\#10471}%
\begin{footnote}[752]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10471}
%
\end{footnote},
by Emilio Jesús Gallego Arias).

\end{itemize}


\paragraph{Changes in 8.11.0}
\label{\detokenize{changes:changes-in-8-11-0}}
\sphinxAtStartPar
\sphinxstylestrong{Kernel}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} the native compilation ({\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}) now
creates a directory to contain temporary files instead of putting
them in the root of the system temporary directory (\sphinxhref{https://github.com/coq/coq/pull/11081}{\#11081}%
\begin{footnote}[753]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11081}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} \sphinxhref{https://github.com/issues/11360}{\#11360}%
\begin{footnote}[754]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/issues/11360}
%
\end{footnote}.
Broken section closing when a template polymorphic inductive type depends on
a section variable through its parameters (\sphinxhref{https://github.com/coq/coq/pull/11361}{\#11361}%
\begin{footnote}[755]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11361}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} The type of \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}\DUrole{operator}{+}\DUrole{literal,number,integer}{1}}} would be computed to be itself,
leading to a proof of False (\sphinxhref{https://github.com/coq/coq/pull/11422}{\#11422}%
\begin{footnote}[756]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11422}
%
\end{footnote}, by Gaëtan Gilbert).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Specification language, type inference}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} Heuristics for universe minimization to \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}: only
minimize flexible universes (\sphinxhref{https://github.com/coq/coq/pull/10657}{\#10657}%
\begin{footnote}[757]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10657}
%
\end{footnote},
by Gaëtan Gilbert with help from Maxime Dénès and Matthieu Sozeau).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
A dependency was missing when looking for default clauses in the
algorithm for printing pattern matching clauses (\sphinxhref{https://github.com/coq/coq/pull/11233}{\#11233}%
\begin{footnote}[758]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11233}
%
\end{footnote}, by Hugo Herbelin, fixing
\sphinxhref{https://github.com/coq/coq/pull/11231}{\#11231}%
\begin{footnote}[759]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11231}
%
\end{footnote}, reported by Barry
Jay).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Notations}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Visibility}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Visibility}}}}} was failing in the presence of only\sphinxhyphen{}printing notations
(\sphinxhref{https://github.com/coq/coq/pull/11276}{\#11276}%
\begin{footnote}[760]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11276}
%
\end{footnote},
by Hugo Herbelin, fixing \sphinxhref{https://github.com/coq/coq/pull/10750}{\#10750}%
\begin{footnote}[761]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10750}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Recursive notations with custom entries were incorrectly parsing \sphinxcode{\sphinxupquote{constr}}
instead of custom grammars (\sphinxhref{https://github.com/coq/coq/pull/11311}{\#11311}%
\begin{footnote}[762]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11311}
%
\end{footnote}
by Maxime Dénès, fixes \sphinxhref{https://github.com/coq/coq/pull/9532}{\#9532}%
\begin{footnote}[763]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9532}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/9490}{\#9490}%
\begin{footnote}[764]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9490}
%
\end{footnote}).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactics}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
The tactics {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} and variants no
longer allow shelved goals to be solved by typeclass resolution
(\sphinxhref{https://github.com/coq/coq/pull/10762}{\#10762}%
\begin{footnote}[765]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10762}
%
\end{footnote}, by Matthieu Sozeau).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:} The optional string argument to {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.time}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{time}}}}} is now
properly quoted under {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.Print-Ltac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Ltac}}}}} (\sphinxhref{https://github.com/coq/coq/pull/11203}{\#11203}%
\begin{footnote}[766]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11203}
%
\end{footnote}, fixes \sphinxhref{https://github.com/coq/coq/issues/10971}{\#10971}%
\begin{footnote}[767]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10971}
%
\end{footnote}, by Jason Gross)

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Efficiency regression of {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} introduced in 8.10
by PR \sphinxhref{https://github.com/coq/coq/pull/9725}{\#9725}%
\begin{footnote}[768]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9725}
%
\end{footnote}
(\sphinxhref{https://github.com/coq/coq/pull/11263}{\#11263}%
\begin{footnote}[769]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11263}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11063}{\#11063}%
\begin{footnote}[770]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11063}
%
\end{footnote},
and \sphinxhref{https://github.com/coq/coq/issues/11242}{\#11242}%
\begin{footnote}[771]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11242}
%
\end{footnote},
and \sphinxhref{https://github.com/coq/coq/issues/11270}{\#11270}%
\begin{footnote}[772]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11270}
%
\end{footnote}, by Frédéric Besson).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:}
The undocumented \sphinxcode{\sphinxupquote{omega with}} tactic variant has been deprecated.
Using {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} is the recommended replacement, though the old semantics
of \sphinxcode{\sphinxupquote{omega with *}} can be recovered with \sphinxcode{\sphinxupquote{zify; omega}}
(\sphinxhref{https://github.com/coq/coq/pull/11337}{\#11337}%
\begin{footnote}[773]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11337}
%
\end{footnote},
by Emilio Jesus Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed}
For compatibility reasons, in 8.11, {\hyperref[\detokenize{addendum/micromega:coq:tacn.zify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{zify}}}}} does not support \sphinxcode{\sphinxupquote{\DUrole{name}{Z}\DUrole{operator}{.}\DUrole{name}{pow\_pos}}} by default.
It can be enabled by explicitly loading the module \sphinxcode{\sphinxupquote{\DUrole{name}{ZifyPow}}}
(\sphinxhref{https://github.com/coq/coq/pull/11430}{\#11430}%
\begin{footnote}[774]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11430}
%
\end{footnote} by Frédéric Besson
fixes \sphinxhref{https://github.com/coq/coq/issues/11191}{\#11191}%
\begin{footnote}[775]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11191}
%
\end{footnote}).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactic language}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Syntax of tactic \sphinxcode{\sphinxupquote{cofix ... with ...}} was broken since Coq 8.10
(\sphinxhref{https://github.com/coq/coq/pull/11241}{\#11241}%
\begin{footnote}[776]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11241}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Commands and options}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:} The \sphinxcode{\sphinxupquote{\sphinxhyphen{}load\sphinxhyphen{}ml\sphinxhyphen{}source}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}load\sphinxhyphen{}ml\sphinxhyphen{}object}} command
line options have been deprecated; their use was very limited, you
can achieve the same by adding object files in the linking step or
by using a plugin (\sphinxhref{https://github.com/coq/coq/pull/11428}{\#11428}%
\begin{footnote}[777]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11428}
%
\end{footnote}, by Emilio Jesus Gallego
Arias).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tools}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
\sphinxcode{\sphinxupquote{coqtop \sphinxhyphen{}\sphinxhyphen{}version}} was broken when called in the middle of an installation process
(\sphinxhref{https://github.com/coq/coq/pull/11255}{\#11255}%
\begin{footnote}[778]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11255}
%
\end{footnote}, by Hugo Herbelin, fixing
\sphinxhref{https://github.com/coq/coq/pull/11254}{\#11254}%
\begin{footnote}[779]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11254}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Deprecated:} The \sphinxcode{\sphinxupquote{\sphinxhyphen{}quick}} command is renamed to \sphinxcode{\sphinxupquote{\sphinxhyphen{}vio}}, for
consistency with the new \sphinxcode{\sphinxupquote{\sphinxhyphen{}vos}} and \sphinxcode{\sphinxupquote{\sphinxhyphen{}vok}} flags. Usage of
\sphinxcode{\sphinxupquote{\sphinxhyphen{}quick}} is now deprecated (\sphinxhref{https://github.com/coq/coq/pull/11280}{\#11280}%
\begin{footnote}[780]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11280}
%
\end{footnote}, by Arthur Charguéraud).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
\sphinxcode{\sphinxupquote{coq\_makefile}} does not break when using the \sphinxcode{\sphinxupquote{CAMLPKGS}} variable
together with an unpacked (\sphinxcode{\sphinxupquote{mllib}}) plugin (\sphinxhref{https://github.com/coq/coq/pull/11357}{\#11357}%
\begin{footnote}[781]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11357}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
\sphinxcode{\sphinxupquote{coqdoc}} with option \sphinxcode{\sphinxupquote{\sphinxhyphen{}g}} (Gallina only) now correctly prints
commands with attributes (\sphinxhref{https://github.com/coq/coq/pull/11394}{\#11394}%
\begin{footnote}[782]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11394}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11353}{\#11353}%
\begin{footnote}[783]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11353}
%
\end{footnote},
by Karl Palmskog).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{CoqIDE}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:} CoqIDE now uses the GtkSourceView native implementation
of the autocomplete mechanism (\sphinxhref{https://github.com/coq/coq/pull/11400}{\#11400}%
\begin{footnote}[784]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11400}
%
\end{footnote}, by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Standard library}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Removed:} Export of module \sphinxcode{\sphinxupquote{\DUrole{name}{RList}}} in \sphinxcode{\sphinxupquote{\DUrole{name}{Ranalysis}}} and
\sphinxcode{\sphinxupquote{\DUrole{name}{Ranalysis\_reg}}}. Module \sphinxcode{\sphinxupquote{\DUrole{name}{RList}}} is still there but must be
imported explicitly where required (\sphinxhref{https://github.com/coq/coq/pull/11396}{\#11396}%
\begin{footnote}[785]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11396}
%
\end{footnote}, by Michael Soegtrop).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Infrastructure and dependencies}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Build date can now be overridden by setting the \sphinxcode{\sphinxupquote{SOURCE\_DATE\_EPOCH}}
environment variable
(\sphinxhref{https://github.com/coq/coq/pull/11227}{\#11227}%
\begin{footnote}[786]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11227}
%
\end{footnote},
by Bernhard M. Wiedemann).

\end{itemize}


\paragraph{Changes in 8.11.1}
\label{\detokenize{changes:changes-in-8-11-1}}
\sphinxAtStartPar
\sphinxstylestrong{Kernel}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Allow more inductive types in \sphinxcode{\sphinxupquote{Unset Positivity Checking}} mode
(\sphinxhref{https://github.com/coq/coq/pull/11811}{\#11811}%
\begin{footnote}[787]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11811}
%
\end{footnote},
by SimonBoulier).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Notations}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Bugs in dealing with precedences of notations in custom entries
(\sphinxhref{https://github.com/coq/coq/pull/11530}{\#11530}%
\begin{footnote}[788]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11530}
%
\end{footnote},
by Hugo Herbelin, fixing in particular
\sphinxhref{https://github.com/coq/coq/pull/9517}{\#9517}%
\begin{footnote}[789]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9517}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/9519}{\#9519}%
\begin{footnote}[790]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9519}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/9521}{\#9521}%
\begin{footnote}[791]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9521}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11331}{\#11331}%
\begin{footnote}[792]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11331}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
In primitive floats, print a warning when parsing a decimal value
that is not exactly a binary64 floating\sphinxhyphen{}point number.
For instance, parsing 0.1 will print a warning whereas parsing 0.5 won't.
(\sphinxhref{https://github.com/coq/coq/pull/11859}{\#11859}%
\begin{footnote}[793]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11859}
%
\end{footnote},
by Pierre Roux).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{CoqIDE}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Compiling file paths containing spaces
(\sphinxhref{https://github.com/coq/coq/pull/10008}{\#10008}%
\begin{footnote}[794]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10008}
%
\end{footnote},
by snyke7, fixing \sphinxhref{https://github.com/coq/coq/pull/11595}{\#11595}%
\begin{footnote}[795]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11595}
%
\end{footnote}).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Infrastructure and dependencies}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Added:}
Bump official OCaml support and CI testing to 4.10.0
(\sphinxhref{https://github.com/coq/coq/pull/11131}{\#11131}%
\begin{footnote}[796]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11131}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11123}{\#11123}%
\begin{footnote}[797]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11123}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/11102}{\#11102}%
\begin{footnote}[798]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11102}
%
\end{footnote},
by Emilio Jesus Gallego Arias, Jacques\sphinxhyphen{}Henri Jourdan,
Guillaume Melquiond, and Guillaume Munch\sphinxhyphen{}Maccagnoni).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Miscellaneous}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
{\hyperref[\detokenize{addendum/extraction:coq:cmd.Extraction-Implicit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Implicit}}}}} on the constructor of a record was leading to an anomaly
(\sphinxhref{https://github.com/coq/coq/pull/11329}{\#11329}%
\begin{footnote}[799]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11329}
%
\end{footnote},
by Hugo Herbelin, fixes \sphinxhref{https://github.com/coq/coq/pull/11114}{\#11114}%
\begin{footnote}[800]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11114}
%
\end{footnote}).

\end{itemize}


\paragraph{Changes in 8.11.2}
\label{\detokenize{changes:changes-in-8-11-2}}
\sphinxAtStartPar
\sphinxstylestrong{Kernel}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Using {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} inside a section caused an anomaly when closing
the section. (\sphinxhref{https://github.com/coq/coq/pull/11972}{\#11972}%
\begin{footnote}[801]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11972}
%
\end{footnote}, by
Gaëtan Gilbert, fixing \sphinxhref{https://github.com/coq/coq/issues/11783}{\#11783}%
\begin{footnote}[802]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11783}
%
\end{footnote}, reported by Attila
Boros).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactics}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Anomaly with induction schemes whose conclusion is not normalized
(\sphinxhref{https://github.com/coq/coq/pull/12116}{\#12116}%
\begin{footnote}[803]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12116}
%
\end{footnote},
by Hugo Herbelin; fixes
\sphinxhref{https://github.com/coq/coq/pull/12045}{\#12045}%
\begin{footnote}[804]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12045}
%
\end{footnote})

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Loss of location of some tactic errors
(\sphinxhref{https://github.com/coq/coq/pull/12223}{\#12223}%
\begin{footnote}[805]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12223}
%
\end{footnote},
by Hugo Herbelin; fixes
\sphinxhref{https://github.com/coq/coq/pull/12152}{\#12152}%
\begin{footnote}[806]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12152}
%
\end{footnote} and
\sphinxhref{https://github.com/coq/coq/pull/12255}{\#12255}%
\begin{footnote}[807]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12255}
%
\end{footnote}).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Commands and options}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
Ignore \sphinxhyphen{}native\sphinxhyphen{}compiler option when built without native compute
support.
(\sphinxhref{https://github.com/coq/coq/pull/12070}{\#12070}%
\begin{footnote}[808]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12070}
%
\end{footnote},
by Pierre Roux).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{CoqIDE}
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Changed:}
CoqIDE now uses native window frames by default on Windows.
The GTK window frames can be restored by setting the \sphinxcode{\sphinxupquote{GTK\_CSD}} environment variable to \sphinxcode{\sphinxupquote{1}}
(\sphinxhref{https://github.com/coq/coq/pull/12060}{\#12060}%
\begin{footnote}[809]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12060}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11080}{\#11080}%
\begin{footnote}[810]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11080}
%
\end{footnote},
by Attila Gáspár).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
New patch presumably fixing the random Coq 8.11 segfault issue with CoqIDE completion
(\sphinxhref{https://github.com/coq/coq/pull/12068}{\#12068}%
\begin{footnote}[811]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12068}
%
\end{footnote},
by Hugo Herbelin, presumably fixing
\sphinxhref{https://github.com/coq/coq/pull/11943}{\#11943}%
\begin{footnote}[812]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11943}
%
\end{footnote}).

\item {} 
\sphinxAtStartPar
\sphinxstylestrong{Fixed:}
Highlighting style consistently applied to all three buffers of CoqIDE
(\sphinxhref{https://github.com/coq/coq/pull/12106}{\#12106}%
\begin{footnote}[813]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/12106}
%
\end{footnote},
by Hugo Herbelin; fixes
\sphinxhref{https://github.com/coq/coq/pull/11506}{\#11506}%
\begin{footnote}[814]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11506}
%
\end{footnote}).

\end{itemize}


\subsubsection{Version 8.10}
\label{\detokenize{changes:version-8-10}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id793}}
\sphinxAtStartPar
Coq version 8.10 contains two major new features: support for a native
fixed\sphinxhyphen{}precision integer type and a new sort \(\SProp\) of strict
propositions. It is also the result of refinements and stabilization of
previous features, deprecations or removals of deprecated features,
cleanups of the internals of the system and API, and many documentation improvements.
This release includes many user\sphinxhyphen{}visible changes, including deprecations that are
documented in the next subsection, and new features that are documented in the
reference manual. Here are the most important user\sphinxhyphen{}visible changes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Kernel:
\begin{itemize}
\item {} 
\sphinxAtStartPar
A notion of primitive object was added to the calculus. Its first
instance is primitive cyclic unsigned integers, axiomatized in
module \sphinxcode{\sphinxupquote{\DUrole{name}{UInt63}}}. See Section {\hyperref[\detokenize{language/core/primitive:primitive-integers}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Integers}}}}.
The \sphinxcode{\sphinxupquote{Coq.Numbers.Cyclic.Int31}} library is deprecated
(\sphinxhref{https://github.com/coq/coq/pull/6914}{\#6914}%
\begin{footnote}[815]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/6914}
%
\end{footnote}, by Maxime Dénès,
Benjamin Grégoire and Vincent Laporte,
with help and reviews from many others).

\item {} 
\sphinxAtStartPar
The \(\SProp\) sort of definitionally proof\sphinxhyphen{}irrelevant propositions was
introduced. \(\SProp\) allows to mark proof
terms as irrelevant for conversion, and is treated like \(\Prop\)
during extraction. It is enabled using the \sphinxcode{\sphinxupquote{\sphinxhyphen{}allow\sphinxhyphen{}sprop}}
command\sphinxhyphen{}line flag or the {\hyperref[\detokenize{addendum/sprop:coq:flag.Allow-StrictProp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Allow StrictProp}}}}} flag.
See Chapter {\hyperref[\detokenize{addendum/sprop:sprop}]{\sphinxcrossref{\DUrole{std,std-ref}{SProp (proof irrelevant propositions)}}}}
(\sphinxhref{https://github.com/coq/coq/pull/8817}{\#8817}%
\begin{footnote}[816]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8817}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
The unfolding heuristic in termination checking was made more
complete, allowing more constants to be unfolded to discover valid
recursive calls.  Performance regression may occur in Fixpoint
declarations without an explicit \sphinxcode{\sphinxupquote{\{struct\}}} annotation, since
guessing the decreasing argument can now be more expensive
(\sphinxhref{https://github.com/coq/coq/pull/9602}{\#9602}%
\begin{footnote}[817]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9602}
%
\end{footnote}, by Enrico Tassi).

\end{itemize}

\item {} 
\sphinxAtStartPar
Universes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added Subgraph variant to {\hyperref[\detokenize{addendum/universe-polymorphism:coq:cmd.Print-Universes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Universes}}}}}.
Try for instance
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Print} \DUrole{name}{Universes} \DUrole{name}{Subgraph}\DUrole{operator}{(}\DUrole{name}{sigT2}\DUrole{operator}{.}\DUrole{name}{u1} \DUrole{name}{sigT\_of\_sigT2}\DUrole{operator}{.}\DUrole{name}{u1} \DUrole{name}{projT3\_eq}\DUrole{operator}{.}\DUrole{name}{u1}\DUrole{operator}{).}}}
(\sphinxhref{https://github.com/coq/coq/pull/8451}{\#8451}%
\begin{footnote}[818]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8451}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
Added private universes for opaque polymorphic constants, see the
documentation for the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Private-Polymorphic-Universes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Private Polymorphic Universes}}}}} flag,
and unset it to get the previous behaviour
(\sphinxhref{https://github.com/coq/coq/pull/8850}{\#8850}%
\begin{footnote}[819]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8850}
%
\end{footnote}, by Gaëtan Gilbert).

\end{itemize}

\item {} 
\sphinxAtStartPar
Notations:
\begin{itemize}
\item {} 
\sphinxAtStartPar
New command {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.String-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{String Notation}}}}} to register string syntax for custom
inductive types
(\sphinxhref{https://github.com/coq/coq/pull/8965}{\#8965}%
\begin{footnote}[820]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8965}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
Experimental: {\hyperref[\detokenize{user-extensions/syntax-extensions:number-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Number Notations}}}} now parse decimal
constants such as \sphinxcode{\sphinxupquote{1.02e+01}} or \sphinxcode{\sphinxupquote{10.2}}. Parsers added for \sphinxcode{\sphinxupquote{\DUrole{name}{Q}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{R}}}.
In the rare case when such numeral notations were used
in a development along with \sphinxcode{\sphinxupquote{\DUrole{name}{Q}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{R}}}, they may have to be removed or
disambiguated through explicit scope annotations
(\sphinxhref{https://github.com/coq/coq/pull/8764}{\#8764}%
\begin{footnote}[821]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8764}
%
\end{footnote}, by Pierre Roux).

\end{itemize}

\item {} 
\sphinxAtStartPar
Ltac backtraces can be turned on using the {\hyperref[\detokenize{proof-engine/ltac:coq:flag.Ltac-Backtrace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac Backtrace}}}}}
flag, which is off by default
(\sphinxhref{https://github.com/coq/coq/pull/9142}{\#9142}%
\begin{footnote}[822]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9142}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/7769}{\#7769}%
\begin{footnote}[823]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7769}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/7385}{\#7385}%
\begin{footnote}[824]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7385}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
The tactics {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}}, {\hyperref[\detokenize{addendum/micromega:coq:tacn.nia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nia}}}}}, {\hyperref[\detokenize{addendum/micromega:coq:tacn.lra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lra}}}}}, {\hyperref[\detokenize{addendum/micromega:coq:tacn.nra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nra}}}}} are now using a novel
Simplex\sphinxhyphen{}based proof engine. In case of regression, unset {\hyperref[\detokenize{addendum/micromega:coq:flag.Simplex}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Simplex}}}}}
to get the venerable Fourier\sphinxhyphen{}based engine
(\sphinxhref{https://github.com/coq/coq/pull/8457}{\#8457}%
\begin{footnote}[825]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8457}
%
\end{footnote}, by Fréderic Besson).

\item {} 
\sphinxAtStartPar
SSReflect:
\begin{itemize}
\item {} 
\sphinxAtStartPar
New intro patterns:
\begin{itemize}
\item {} 
\sphinxAtStartPar
temporary introduction: \sphinxcode{\sphinxupquote{=> +}}

\item {} 
\sphinxAtStartPar
block introduction: \sphinxcode{\sphinxupquote{=> {[}\textasciicircum{} prefix {]} {[}\textasciicircum{}\textasciitilde{} suffix {]}}}

\item {} 
\sphinxAtStartPar
fast introduction: \sphinxcode{\sphinxupquote{=> >}}

\item {} 
\sphinxAtStartPar
tactics as views: \sphinxcode{\sphinxupquote{=> /ltac:mytac}}

\item {} 
\sphinxAtStartPar
replace hypothesis: \sphinxcode{\sphinxupquote{=> \{\}H}}

\sphinxAtStartPar
See Section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}
(\sphinxhref{https://github.com/coq/coq/pull/6705}{\#6705}%
\begin{footnote}[826]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/6705}
%
\end{footnote}, by Enrico Tassi,
with help from Maxime Dénès,
ideas coming from various users).

\end{itemize}

\item {} 
\sphinxAtStartPar
New tactic {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.under}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{under}}}}} to rewrite under binders, given an
extensionality lemma:
\begin{itemize}
\item {} 
\sphinxAtStartPar
interactive mode: \sphinxcode{\sphinxupquote{\DUrole{notation}{under {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, associated terminator: {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.over}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{over}}}}}

\item {} 
\sphinxAtStartPar
one\sphinxhyphen{}liner mode: \sphinxcode{\sphinxupquote{\DUrole{notation}{under {\hyperref[\detokenize{language/core/basic:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} do {[}{\hyperref[\detokenize{language/core/basic:grammar-token-tactic}]{\sphinxcrossref{\DUrole{hole}{tactic}}}} | ...{]}}}}

\end{itemize}

\sphinxAtStartPar
It can take occurrence switches, contextual patterns, and intro patterns:
\sphinxcode{\sphinxupquote{\DUrole{name}{under} \DUrole{operator}{\{}\DUrole{literal,number,integer}{2}\DUrole{operator}{\}{[}}\DUrole{keyword}{in} \DUrole{name}{RHS}\DUrole{operator}{{]}}\DUrole{name}{eq\_big} \DUrole{operator}{=>} \DUrole{operator}{{[}}\DUrole{name}{i}\DUrole{operator}{|}\DUrole{name}{i} \DUrole{operator}{?{]}}}}
(\sphinxhref{https://github.com/coq/coq/pull/9651}{\#9651}%
\begin{footnote}[827]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9651}
%
\end{footnote},
by Erik Martin\sphinxhyphen{}Dorel and Enrico Tassi).

\end{itemize}

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:cmd.Combined-Scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Combined Scheme}}}}} now works when inductive schemes are generated in sort
\(\Type\). It used to be limited to sort \sphinxcode{\sphinxupquote{Prop}}
(\sphinxhref{https://github.com/coq/coq/pull/7634}{\#7634}%
\begin{footnote}[828]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7634}
%
\end{footnote}, by Théo Winterhalter).

\item {} 
\sphinxAtStartPar
A new registration mechanism for reference from ML code to Coq
constructs has been added
(\sphinxhref{https://github.com/coq/coq/pull/186}{\#186}%
\begin{footnote}[829]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/186}
%
\end{footnote},
by Emilio Jesús Gallego Arias, Maxime Dénès and Vincent Laporte).

\item {} 
\sphinxAtStartPar
CoqIDE:
\begin{itemize}
\item {} 
\sphinxAtStartPar
CoqIDE now depends on gtk+3 and lablgtk3 instead of gtk+2 and lablgtk2.
The INSTALL file available in the Coq sources has been updated to list
the new dependencies
(\sphinxhref{https://github.com/coq/coq/pull/9279}{\#9279}%
\begin{footnote}[830]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9279}
%
\end{footnote},
by Hugo Herbelin, with help from Jacques Garrigue,
Emilio Jesús Gallego Arias, Michael Sogetrop and Vincent Laporte).

\item {} 
\sphinxAtStartPar
Smart input for Unicode characters. For example, typing
\sphinxcode{\sphinxupquote{\textbackslash{}alpha}} then \sphinxcode{\sphinxupquote{Shift+Space}} will insert the greek letter alpha.
A larger number of default bindings are provided, following the latex
naming convention. Bindings can be customized, either globally, or on a
per\sphinxhyphen{}project basis. See Section {\hyperref[\detokenize{practical-tools/coqide:coqide-unicode}]{\sphinxcrossref{\DUrole{std,std-ref}{Bindings for input of Unicode symbols}}}} for details
(\sphinxhref{https://github.com/coq/coq/pull/8560}{\#8560}%
\begin{footnote}[831]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8560}
%
\end{footnote}, by Arthur Charguéraud).

\end{itemize}

\item {} 
\sphinxAtStartPar
Infrastructure and dependencies:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Coq 8.10 requires OCaml >= 4.05.0, bumped from 4.02.3 See the
\sphinxcode{\sphinxupquote{INSTALL}} file for more information on dependencies
(\sphinxhref{https://github.com/coq/coq/pull/7522}{\#7522}%
\begin{footnote}[832]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7522}
%
\end{footnote}, by Emilio Jesús Gallego Arías).

\item {} 
\sphinxAtStartPar
Coq 8.10 doesn't need Camlp5 to build anymore. It now includes a
fork of the core parsing library that Coq uses, which is a small
subset of the whole Camlp5 distribution. In particular, this subset
doesn't depend on the OCaml AST, allowing easier compilation and
testing on experimental OCaml versions. Coq also ships a new parser
\sphinxcode{\sphinxupquote{coqpp}} that plugin authors must switch to
(\sphinxhref{https://github.com/coq/coq/pull/7902}{\#7902}%
\begin{footnote}[833]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7902}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/7979}{\#7979}%
\begin{footnote}[834]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7979}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/8161}{\#8161}%
\begin{footnote}[835]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8161}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/8667}{\#8667}%
\begin{footnote}[836]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8667}
%
\end{footnote},
and \sphinxhref{https://github.com/coq/coq/pull/8945}{\#8945}%
\begin{footnote}[837]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8945}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot and Emilio Jesús Gallego Arias).

\sphinxAtStartPar
The Coq developers would like to thank Daniel de Rauglaudre for many
years of continued support.

\item {} 
\sphinxAtStartPar
Coq now supports building with Dune, in addition to the traditional
Makefile which is scheduled for deprecation
(\sphinxhref{https://github.com/coq/coq/pull/6857}{\#6857}%
\begin{footnote}[838]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/6857}
%
\end{footnote},
by Emilio Jesús Gallego Arias, with help from Rudi Grinberg).

\sphinxAtStartPar
Experimental support for building Coq projects has been integrated
in Dune at the same time, providing an \sphinxhref{https://coq.discourse.group/t/a-guide-to-building-your-coq-libraries-and-plugins-with-dune/}{improved experience}%
\begin{footnote}[839]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.discourse.group/t/a-guide-to-building-your-coq-libraries-and-plugins-with-dune/}
%
\end{footnote}
for plugin developers. We thank the Dune team for their work
supporting Coq.

\end{itemize}

\end{itemize}

\sphinxAtStartPar
Version 8.10 also comes with a bunch of smaller\sphinxhyphen{}scale changes and
improvements regarding the different components of the system, including
many additions to the standard library (see the next subsection for details).

\sphinxAtStartPar
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 and a plugin development tutorial originally made by Yves Bertot
is now in \sphinxcode{\sphinxupquote{doc/plugin\_tutorial}}. The \sphinxcode{\sphinxupquote{dev/doc/critical\sphinxhyphen{}bugs}} file
documents the known critical bugs of Coq and affected releases.

\sphinxAtStartPar
The efficiency of the whole system has seen improvements thanks to
contributions from Gaëtan Gilbert, Pierre\sphinxhyphen{}Marie Pédrot, and Maxime Dénès.

\sphinxAtStartPar
Maxime Dénès, Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop, Théo Zimmermann worked on maintaining and improving the
continuous integration system and package building infrastructure.
Coq is now continuously tested against the OCaml trunk, in addition to the
oldest supported and latest OCaml releases.

\sphinxAtStartPar
Coq's documentation for the development branch is now deployed
continuously at \sphinxurl{https://coq.github.io/doc/master/api} (documentation of
the ML API), \sphinxurl{https://coq.github.io/doc/master/refman} (reference
manual), and \sphinxurl{https://coq.github.io/doc/master/stdlib} (documentation of
the standard library). Similar links exist for the \sphinxcode{\sphinxupquote{v8.10}} branch.

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

\sphinxAtStartPar
The 61 contributors to this version are Tanaka Akira, Benjamin
Barenblat, Yves Bertot, Frédéric Besson, Lasse Blaauwbroek, Martin
Bodin, Joachim Breitner, Tej Chajed, Frédéric Chapoton, Arthur
Charguéraud, Cyril Cohen, Lukasz Czajka, David A. Dalrymple, Christian
Doczkal, Maxime Dénès, Andres Erbsen, Jim Fehrle, Emilio Jesus Gallego
Arias, Gaëtan Gilbert, Matěj Grabovský, Simon Gregersen, Jason Gross,
Samuel Gruetter, Hugo Herbelin, Jasper Hugunin, Mirai Ikebuchi,
Chantal Keller, Matej Košík, Sam Pablo Kuper, Vincent Laporte, Olivier
Laurent, Larry Darryl Lee Jr, Nick Lewycky, Yao Li, Yishuai Li, Assia
Mahboubi, Simon Marechal, Erik Martin\sphinxhyphen{}Dorel, Thierry Martinez,
Guillaume Melquiond, Kayla Ngan, Karl Palmskog, Pierre\sphinxhyphen{}Marie Pédrot,
Clément Pit\sphinxhyphen{}Claudel, Pierre Roux, Kazuhiko Sakaguchi, Ryan Scott,
Vincent Semeria, Gan Shen, Michael Soegtrop, Matthieu Sozeau, Enrico
Tassi, Laurent Théry, Kamil Trzciński, whitequark, Théo Winterhalter,
Xia Li\sphinxhyphen{}yao, Beta Ziliani and Théo Zimmermann.

\sphinxAtStartPar
Many power users helped to improve the design of the new features via
the issue and pull request system, the Coq development mailing list,
the \sphinxhref{mailto:coq-club@inria.fr}{coq\sphinxhyphen{}club@inria.fr} mailing list or the new Discourse forum. It would
be impossible to mention exhaustively the names of everybody who to some
extent influenced the development.

\sphinxAtStartPar
Version 8.10 is the fifth release of Coq developed on a time\sphinxhyphen{}based
development cycle. Its development spanned 6 months from the release of
Coq 8.9. Vincent Laporte is the release manager and maintainer of this
release. This release is the result of \textasciitilde{}2500 commits and \textasciitilde{}650 PRs merged,
closing 150+ issues.

\begin{DUlineblock}{0em}
\item[] Santiago de Chile, April 2019,
\item[] Matthieu Sozeau for the Coq development team
\item[] 
\end{DUlineblock}


\paragraph{Other changes in 8.10+beta1}
\label{\detokenize{changes:other-changes-in-8-10-beta1}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Command\sphinxhyphen{}line tools and options:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The use of \sphinxcode{\sphinxupquote{coqtop}} as a compiler has been deprecated, in favor of
\sphinxcode{\sphinxupquote{coqc}}. Consequently option \sphinxcode{\sphinxupquote{\sphinxhyphen{}compile}} will stop to be accepted in
the next release. \sphinxcode{\sphinxupquote{coqtop}} is now reserved to interactive
use
(\sphinxhref{https://github.com/coq/coq/pull/9095}{\#9095}%
\begin{footnote}[840]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9095}
%
\end{footnote},
by Emilio Jesús Gallego Arias).

\item {} 
\sphinxAtStartPar
New option \sphinxcode{\sphinxupquote{\sphinxhyphen{}topfile filename}}, which will set the current module name
(\sphinxstyleemphasis{à la} \sphinxcode{\sphinxupquote{\sphinxhyphen{}top}}) based on the filename passed, taking into account the
proper \sphinxcode{\sphinxupquote{\sphinxhyphen{}R}}/\sphinxcode{\sphinxupquote{\sphinxhyphen{}Q}} options. For example, given \sphinxcode{\sphinxupquote{\sphinxhyphen{}R Foo foolib}} using
\sphinxcode{\sphinxupquote{\sphinxhyphen{}topfile foolib/bar.v}} will set the module name to \sphinxcode{\sphinxupquote{Foo.Bar}}.
CoqIDE now properly sets the module name for a given file based on
its path
(\sphinxhref{https://github.com/coq/coq/pull/8991}{\#8991}%
\begin{footnote}[841]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8991}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/8989}{\#8989}%
\begin{footnote}[842]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/8989}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
Experimental: Coq flags and options can now be set on the
command\sphinxhyphen{}line, e.g. \sphinxcode{\sphinxupquote{\sphinxhyphen{}set "Universe Polymorphism=true"}}
(\sphinxhref{https://github.com/coq/coq/pull/9876}{\#9876}%
\begin{footnote}[843]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9876}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{\sphinxhyphen{}native\sphinxhyphen{}compiler}} flag of \sphinxcode{\sphinxupquote{coqc}} and \sphinxcode{\sphinxupquote{coqtop}} now takes an
argument which can have three values:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{no}} disables native\_compute

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{yes}} enables native\_compute and precompiles \sphinxcode{\sphinxupquote{.v}} files to
native code

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{ondemand}} enables native\_compute but compiles code only when
\sphinxcode{\sphinxupquote{native\_compute}} is called

\end{itemize}

\sphinxAtStartPar
The default value is \sphinxcode{\sphinxupquote{ondemand}}. Note that this flag now has
priority over the configure flag of the same name.

\sphinxAtStartPar
A new \sphinxcode{\sphinxupquote{\sphinxhyphen{}bytecode\sphinxhyphen{}compiler}} flag for \sphinxcode{\sphinxupquote{coqc}} and \sphinxcode{\sphinxupquote{coqtop}} controls
whether conversion can use the VM. The default value is \sphinxcode{\sphinxupquote{yes}}.

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/8870}{\#8870}%
\begin{footnote}[844]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8870}
%
\end{footnote}, by Maxime Dénès)

\item {} 
\sphinxAtStartPar
The pretty timing diff scripts (flag \sphinxcode{\sphinxupquote{TIMING=1}} to a
\sphinxcode{\sphinxupquote{coq\_makefile}}\sphinxhyphen{}made \sphinxcode{\sphinxupquote{Makefile}}, also
\sphinxcode{\sphinxupquote{tools/make\sphinxhyphen{}both\sphinxhyphen{}single\sphinxhyphen{}timing\sphinxhyphen{}files.py}},
\sphinxcode{\sphinxupquote{tools/make\sphinxhyphen{}both\sphinxhyphen{}time\sphinxhyphen{}files.py}}, and \sphinxcode{\sphinxupquote{tools/make\sphinxhyphen{}one\sphinxhyphen{}time\sphinxhyphen{}file.py}})
now correctly support non\sphinxhyphen{}UTF\sphinxhyphen{}8 characters in the output of
\sphinxcode{\sphinxupquote{coqc}} / \sphinxcode{\sphinxupquote{make}} as well as printing to stdout, on both python2 and
python3
(\sphinxhref{https://github.com/coq/coq/pull/9872}{\#9872}%
\begin{footnote}[845]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9872}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/9767}{\#9767}%
\begin{footnote}[846]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9767}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/9705}{\#9705}%
\begin{footnote}[847]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9705}
%
\end{footnote},
by Jason Gross)

\item {} 
\sphinxAtStartPar
coq\_makefile's install target now errors if any file to install is missing
(\sphinxhref{https://github.com/coq/coq/pull/9906}{\#9906}%
\begin{footnote}[848]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9906}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
Preferences from \sphinxcode{\sphinxupquote{coqide.keys}} are no longer overridden by
modifiers preferences in \sphinxcode{\sphinxupquote{coqiderc}}
(\sphinxhref{https://github.com/coq/coq/pull/10014}{\#10014}%
\begin{footnote}[849]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10014}
%
\end{footnote}, by Hugo Herbelin).

\end{itemize}

\item {} 
\sphinxAtStartPar
Specification language, type inference:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fixing a missing check in interpreting instances of existential
variables that are bound to local definitions. Might exceptionally
induce an overhead if the cost of checking the conversion of the
corresponding definitions is additionally high
(\sphinxhref{https://github.com/coq/coq/pull/8217}{\#8217}%
\begin{footnote}[850]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8217}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/8215}{\#8215}%
\begin{footnote}[851]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/8215}
%
\end{footnote},
by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
A few improvements in inference of the return clause of \sphinxcode{\sphinxupquote{match}} that
can exceptionally introduce incompatibilities. This can be
solved by writing an explicit \sphinxcode{\sphinxupquote{return}} clause, sometimes even simply
an explicit \sphinxcode{\sphinxupquote{return \_}} clause
(\sphinxhref{https://github.com/coq/coq/pull/262}{\#262}%
\begin{footnote}[852]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/262}
%
\end{footnote}, by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
Using non\sphinxhyphen{}projection values with the projection syntax is not
allowed. For instance \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{0}\DUrole{operator}{.(}\DUrole{name}{S}\DUrole{operator}{)}}} is not a valid way to write \sphinxcode{\sphinxupquote{\DUrole{name}{S} \DUrole{literal,number,integer}{0}}}.
Projections from non\sphinxhyphen{}primitive (emulated) records are allowed with
warning "nonprimitive\sphinxhyphen{}projection\sphinxhyphen{}syntax"
(\sphinxhref{https://github.com/coq/coq/pull/8829}{\#8829}%
\begin{footnote}[853]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8829}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
An option and attributes to control the automatic decision to declare
an inductive type as template polymorphic were added.  Warning
"auto\sphinxhyphen{}template" (off by default) can trigger when an inductive is
automatically declared template polymorphic without the attribute.

\sphinxAtStartPar
Inductive types declared by Funind will never be template polymorphic.

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/8488}{\#8488}%
\begin{footnote}[854]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8488}
%
\end{footnote}, by Gaëtan Gilbert)

\end{itemize}

\item {} 
\sphinxAtStartPar
Notations:
\begin{itemize}
\item {} 
\sphinxAtStartPar
New command {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Declare-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare Scope}}}}} to explicitly declare a scope name
before any use of it. Implicit declaration of a scope at the time of
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Bind-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Bind Scope}}}}}, {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Delimit-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Delimit Scope}}}}}, {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Undelimit-Scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Undelimit Scope}}}}},
or {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} is deprecated
(\sphinxhref{https://github.com/coq/coq/pull/7135}{\#7135}%
\begin{footnote}[855]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7135}
%
\end{footnote}, by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
Various bugs have been fixed (e.g. \sphinxhref{https://github.com/coq/coq/pull/9214}{\#9214}%
\begin{footnote}[856]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9214}
%
\end{footnote} on removing spurious
parentheses on abbreviations shortening a strict prefix of an
application, by Hugo Herbelin).

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} now support inductive types in the input to
printing functions (e.g., numeral notations can be defined for terms
containing things like \sphinxcode{\sphinxupquote{\DUrole{operator}{@}\DUrole{name}{cons} \DUrole{name}{nat} \DUrole{name}{O} \DUrole{name}{O}}}), and parsing functions now
fully normalize terms including parameters of constructors (so that,
e.g., a numeral notation whose parsing function outputs a proof of
\sphinxcode{\sphinxupquote{\DUrole{name}{Nat}\DUrole{operator}{.}\DUrole{name}{gcd} \DUrole{name}{x} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{literal,number,integer}{1}}} will no longer fail to parse due to containing the
constant \sphinxcode{\sphinxupquote{\DUrole{name}{Nat}\DUrole{operator}{.}\DUrole{name}{gcd}}} in the parameter\sphinxhyphen{}argument of \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_refl}}})
(\sphinxhref{https://github.com/coq/coq/pull/9874}{\#9874}%
\begin{footnote}[857]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9874}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/9840}{\#9840}%
\begin{footnote}[858]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9840}
%
\end{footnote}
and \sphinxhref{https://github.com/coq/coq/issues/9844}{\#9844}%
\begin{footnote}[859]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9844}
%
\end{footnote},
by Jason Gross).

\item {} 
\sphinxAtStartPar
Deprecated compatibility notations have actually been
removed. Uses of these notations are generally easy to fix thanks
to the hint contained in the deprecation warning emitted by Coq
8.8 and 8.9.  For projects that require more than a handful of
such fixes, there is \sphinxhref{https://gist.github.com/JasonGross/9770653967de3679d131c59d42de6d17\#file-replace-notations-py}{a script}%
\begin{footnote}[860]\sphinxAtStartFootnote
\sphinxnolinkurl{https://gist.github.com/JasonGross/9770653967de3679d131c59d42de6d17\#file-replace-notations-py}
%
\end{footnote}
that will do it automatically, using the output of \sphinxcode{\sphinxupquote{coqc}}
(\sphinxhref{https://github.com/coq/coq/pull/8638}{\#8638}%
\begin{footnote}[861]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8638}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
Allow inspecting custom grammar entries by {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Print-Custom-Grammar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Custom Grammar}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/10061}{\#10061}%
\begin{footnote}[862]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10061}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/pull/9681}{\#9681}%
\begin{footnote}[863]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9681}
%
\end{footnote},
by Jasper Hugunin, review by Pierre\sphinxhyphen{}Marie Pédrot and Hugo Herbelin).

\end{itemize}

\item {} 
\sphinxAtStartPar
The \sphinxhref{https://coq.inria.fr/distrib/V8.9.0/refman/proof-engine/detailed-tactic-examples.html\#quote}{quote plugin}%
\begin{footnote}[864]\sphinxAtStartFootnote
\sphinxnolinkurl{https://coq.inria.fr/distrib/V8.9.0/refman/proof-engine/detailed-tactic-examples.html\#quote}
%
\end{footnote}
was removed. If some users are interested in maintaining this plugin
externally, the Coq development team can provide assistance for
extracting the plugin and setting up a new repository
(\sphinxhref{https://github.com/coq/coq/pull/7894}{\#7894}%
\begin{footnote}[865]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7894}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
Ltac:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Tactic names are no longer allowed to clash, even if they are not defined in
the same section. For example, the following is no longer accepted:
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Ltac} \DUrole{name}{foo} \DUrole{operator}{:=} \DUrole{keyword,reserved}{idtac}\DUrole{operator}{.} \DUrole{keyword,namespace}{Section} \DUrole{name}{S}\DUrole{operator}{.} \DUrole{keyword,namespace}{Ltac} \DUrole{name}{foo} \DUrole{operator}{:=} \DUrole{name}{fail}\DUrole{operator}{.} \DUrole{keyword,namespace}{End} \DUrole{name}{S}\DUrole{operator}{.}}}
(\sphinxhref{https://github.com/coq/coq/pull/8555}{\#8555}%
\begin{footnote}[866]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8555}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
Names of existential variables occurring in Ltac functions
(e.g. \sphinxcode{\sphinxupquote{\DUrole{operator}{?{[}}\DUrole{name}{n}\DUrole{operator}{{]}}}} or \sphinxcode{\sphinxupquote{\DUrole{operator}{?}\DUrole{name}{n}}} in terms \sphinxhyphen{} not in patterns) are now interpreted
the same way as other variable names occurring in Ltac functions
(\sphinxhref{https://github.com/coq/coq/pull/7309}{\#7309}%
\begin{footnote}[867]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7309}
%
\end{footnote}, by Hugo Herbelin).

\end{itemize}

\item {} 
\sphinxAtStartPar
Tactics:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Removed the deprecated \sphinxcode{\sphinxupquote{romega}} tactic
(\sphinxhref{https://github.com/coq/coq/pull/8419}{\#8419}%
\begin{footnote}[868]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8419}
%
\end{footnote},
by Maxime Dénès and Vincent Laporte).

\item {} 
\sphinxAtStartPar
Hint declaration and removal should now specify a database (e.g. \sphinxcode{\sphinxupquote{Hint Resolve
foo : database}}). When the database name is omitted, the hint is added to the
\sphinxcode{\sphinxupquote{core}} database (as previously), but a deprecation warning is emitted
(\sphinxhref{https://github.com/coq/coq/pull/8987}{\#8987}%
\begin{footnote}[869]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8987}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
There are now tactics in \sphinxcode{\sphinxupquote{PreOmega.v}} called
\sphinxcode{\sphinxupquote{Z.div\_mod\_to\_equations}}, \sphinxcode{\sphinxupquote{Z.quot\_rem\_to\_equations}}, and
\sphinxcode{\sphinxupquote{Z.to\_euclidean\_division\_equations}} (which combines the \sphinxcode{\sphinxupquote{div\_mod}}
and \sphinxcode{\sphinxupquote{quot\_rem}} variants) which allow {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}}, {\hyperref[\detokenize{addendum/micromega:coq:tacn.nia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nia}}}}}, etc to
support \sphinxcode{\sphinxupquote{Z.div}} and \sphinxcode{\sphinxupquote{Z.modulo}} (\sphinxcode{\sphinxupquote{Z.quot}} and \sphinxcode{\sphinxupquote{Z.rem}}, respectively),
by posing the specifying equation for \sphinxcode{\sphinxupquote{Z.div}} and \sphinxcode{\sphinxupquote{Z.modulo}} before
replacing them with atoms
(\sphinxhref{https://github.com/coq/coq/pull/8062}{\#8062}%
\begin{footnote}[870]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8062}
%
\end{footnote}, by Jason Gross).

\item {} 
\sphinxAtStartPar
The syntax of the {\hyperref[\detokenize{addendum/type-classes:coq:tacn.autoapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autoapply}}}}} tactic was fixed to conform with preexisting
documentation: it now takes a \sphinxcode{\sphinxupquote{with}} clause instead of a \sphinxcode{\sphinxupquote{using}} clause
(\sphinxhref{https://github.com/coq/coq/pull/9524}{\#9524}%
\begin{footnote}[871]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9524}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/7632}{\#7632}%
\begin{footnote}[872]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7632}
%
\end{footnote},
by Théo Zimmermann).

\item {} 
\sphinxAtStartPar
Modes are now taken into account by {\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}} for
local hypotheses
(\sphinxhref{https://github.com/coq/coq/pull/9996}{\#9996}%
\begin{footnote}[873]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9996}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/5752}{\#5752}%
\begin{footnote}[874]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/5752}
%
\end{footnote},
by Maxime Dénès, review by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
New variant {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change_no_check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change\_no\_check}}}}} of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}}, usable as a
documented replacement of \sphinxcode{\sphinxupquote{convert\_concl\_no\_check}}
(\sphinxhref{https://github.com/coq/coq/pull/10012}{\#10012}%
\begin{footnote}[875]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10012}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/10017}{\#10017}%
\begin{footnote}[876]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10017}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/10053}{\#10053}%
\begin{footnote}[877]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10053}
%
\end{footnote}, and
\sphinxhref{https://github.com/coq/coq/pull/10059}{\#10059}%
\begin{footnote}[878]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10059}
%
\end{footnote},
by Hugo Herbelin and Paolo G. Giarrusso).

\item {} 
\sphinxAtStartPar
The simplified value returned by {\hyperref[\detokenize{addendum/ring:coq:tacn.field_simplify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{field\_simplify}}}}} is not
always a fraction anymore.  When the denominator is \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{1}}}, it
returns \sphinxcode{\sphinxupquote{\DUrole{name}{x}}} while previously it was returning \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{/}\DUrole{literal,number,integer}{1}}}.  This
change could break codes that were post\sphinxhyphen{}processing application of
{\hyperref[\detokenize{addendum/ring:coq:tacn.field_simplify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{field\_simplify}}}}} to get rid of these \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{/}\DUrole{literal,number,integer}{1}}}
(\sphinxhref{https://github.com/coq/coq/pull/9854}{\#9854}%
\begin{footnote}[879]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9854}
%
\end{footnote},
by Laurent Théry,
with help from Michael Soegtrop, Maxime Dénès, and Vincent Laporte).

\end{itemize}

\item {} 
\sphinxAtStartPar
SSReflect:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Clear discipline made consistent across the entire proof language.
Whenever a clear switch \sphinxcode{\sphinxupquote{\{x..\}}} comes immediately before an existing proof
context entry (used as a view, as a rewrite rule or as name for a new
context entry) then such entry is cleared too.

\sphinxAtStartPar
E.g. The following sentences are elaborated as follows (when H is an existing
proof context entry):
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{=> \{x..\} H}}       \sphinxhyphen{}>  \sphinxcode{\sphinxupquote{=> \{x..H\} H}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{=> \{x..\} /H}}      \sphinxhyphen{}>  \sphinxcode{\sphinxupquote{=> /v \{x..H\}}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{rewrite \{x..\} H}}  \sphinxhyphen{}>  \sphinxcode{\sphinxupquote{rewrite E \{x..H\}}}

\end{itemize}

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/9341}{\#9341}%
\begin{footnote}[880]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9341}
%
\end{footnote}, by Enrico Tassi).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{inE}} now expands \sphinxcode{\sphinxupquote{y in r x}} when \sphinxcode{\sphinxupquote{r}} is a \sphinxcode{\sphinxupquote{simpl\_rel}}.
New \sphinxcode{\sphinxupquote{\{pred T\}}} notation for a \sphinxcode{\sphinxupquote{pred T}} alias in the \sphinxcode{\sphinxupquote{pred\_sort}} coercion
class, simplified \sphinxcode{\sphinxupquote{predType}} interface: \sphinxcode{\sphinxupquote{pred\_class}} and \sphinxcode{\sphinxupquote{mkPredType}}
deprecated, \sphinxcode{\sphinxupquote{\{pred T\}}} and \sphinxcode{\sphinxupquote{PredType}} should be used instead.
\sphinxcode{\sphinxupquote{if c return t then ...}} now expects \sphinxcode{\sphinxupquote{c}} to be a variable bound in \sphinxcode{\sphinxupquote{t}}.
New \sphinxcode{\sphinxupquote{nonPropType}} interface matching types that do \_not\_ have sort \sphinxcode{\sphinxupquote{Prop}}.
New \sphinxcode{\sphinxupquote{relpre R f}} definition for the preimage of a relation R under f
(\sphinxhref{https://github.com/coq/coq/pull/9995}{\#9995}%
\begin{footnote}[881]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9995}
%
\end{footnote}, by Georges Gonthier).

\end{itemize}

\item {} 
\sphinxAtStartPar
Commands:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Binders for an {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} now act more like binders for a {\hyperref[\detokenize{language/core/definitions:coq:cmd.Theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}}.
Names may not be repeated, and may not overlap with section variable names
(\sphinxhref{https://github.com/coq/coq/pull/8820}{\#8820}%
\begin{footnote}[882]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8820}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/8791}{\#8791}%
\begin{footnote}[883]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/8791}
%
\end{footnote},
by Jasper Hugunin).

\item {} 
\sphinxAtStartPar
Removed the deprecated \sphinxcode{\sphinxupquote{Implicit Tactic}} family of commands
(\sphinxhref{https://github.com/coq/coq/pull/8779}{\#8779}%
\begin{footnote}[884]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8779}
%
\end{footnote}, by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Automatic Introduction}} option has been removed and is now the
default
(\sphinxhref{https://github.com/coq/coq/pull/9001}{\#9001}%
\begin{footnote}[885]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9001}
%
\end{footnote},
by Emilio Jesús Gallego Arias).

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Arguments}} now accepts names for arguments provided with \sphinxcode{\sphinxupquote{extra\_scopes}}
(\sphinxhref{https://github.com/coq/coq/pull/9117}{\#9117}%
\begin{footnote}[886]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9117}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
The naming scheme for anonymous binders in a \sphinxcode{\sphinxupquote{Theorem}} has changed to
avoid conflicts with explicitly named binders
(\sphinxhref{https://github.com/coq/coq/pull/9160}{\#9160}%
\begin{footnote}[887]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9160}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/8819}{\#8819}%
\begin{footnote}[888]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/8819}
%
\end{footnote},
by Jasper Hugunin).

\item {} 
\sphinxAtStartPar
Computation of implicit arguments now properly handles local definitions in the
binders for an \sphinxcode{\sphinxupquote{Instance}}, and can be mixed with implicit binders \sphinxcode{\sphinxupquote{\{x : T\}}}
(\sphinxhref{https://github.com/coq/coq/pull/9307}{\#9307}%
\begin{footnote}[889]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9307}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/9300}{\#9300}%
\begin{footnote}[890]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9300}
%
\end{footnote},
by Jasper Hugunin).

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/type-classes:coq:cmd.Declare-Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare Instance}}}}} now requires an instance name.

\sphinxAtStartPar
The flag \sphinxcode{\sphinxupquote{Refine Instance Mode}} has been turned off by default, meaning that
{\hyperref[\detokenize{addendum/type-classes:coq:cmd.Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} no longer opens a proof when a body is provided. The flag
has been deprecated and will be removed in the next version.

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/9270}{\#9270}%
\begin{footnote}[891]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9270}
%
\end{footnote},
and \sphinxhref{https://github.com/coq/coq/pull/9825}{\#9825}%
\begin{footnote}[892]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9825}
%
\end{footnote},
by Maxime Dénès)

\item {} 
\sphinxAtStartPar
Command {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}}, when no body is provided, now always opens
a proof. This is a breaking change, as instance of \sphinxcode{\sphinxupquote{\DUrole{notation}{Instance
{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} is a trivial class will
have to be changed into \sphinxcode{\sphinxupquote{\DUrole{notation}{Instance {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}} := \{\}.}}}
or \sphinxcode{\sphinxupquote{\DUrole{notation}{Instance {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} : {\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}. Proof. Qed.}}}
(\sphinxhref{https://github.com/coq/coq/pull/9274}{\#9274}%
\begin{footnote}[893]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9274}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
The flag {\hyperref[\detokenize{addendum/program:coq:flag.Program-Mode}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Program Mode}}}}} now means that the \sphinxcode{\sphinxupquote{Program}} attribute is enabled
for all commands that support it. In particular, it does not have any effect
on tactics anymore. May cause some incompatibilities
(\sphinxhref{https://github.com/coq/coq/pull/9410}{\#9410}%
\begin{footnote}[894]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9410}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
The algorithm computing implicit arguments now behaves uniformly for primitive
projection and application nodes
(\sphinxhref{https://github.com/coq/coq/pull/9509}{\#9509}%
\begin{footnote}[895]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9509}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/9508}{\#9508}%
\begin{footnote}[896]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9508}
%
\end{footnote},
by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{language/core/assumptions:coq:cmd.Hypotheses}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hypotheses}}}}} and {\hyperref[\detokenize{language/core/assumptions:coq:cmd.Variables}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variables}}}}} can now take implicit
binders inside sections
(\sphinxhref{https://github.com/coq/coq/pull/9364}{\#9364}%
\begin{footnote}[897]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9364}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/9363}{\#9363}%
\begin{footnote}[898]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9363}
%
\end{footnote},
by Jasper Hugunin).

\item {} 
\sphinxAtStartPar
Removed deprecated option \sphinxcode{\sphinxupquote{Automatic Coercions Import}}
(\sphinxhref{https://github.com/coq/coq/pull/8094}{\#8094}%
\begin{footnote}[899]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8094}
%
\end{footnote}, by Maxime Dénès).

\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Show Script}} command has been deprecated
(\sphinxhref{https://github.com/coq/coq/pull/9829}{\#9829}%
\begin{footnote}[900]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9829}
%
\end{footnote}, by Vincent Laporte).

\item {} 
\sphinxAtStartPar
{\hyperref[\detokenize{addendum/implicit-coercions:coq:cmd.Coercion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Coercion}}}}} does not warn ambiguous paths which are obviously
convertible with existing ones. The ambiguous paths messages have been
turned to warnings, thus now they could appear in the output of \sphinxcode{\sphinxupquote{coqc}}.
The convertibility checking procedure for coercion paths is complete for
paths consisting of coercions satisfying the uniform inheritance condition,
but some coercion paths could be reported as ambiguous even if they are
convertible with existing ones when they have coercions that don't satisfy
the uniform inheritance condition
(\sphinxhref{https://github.com/coq/coq/pull/9743}{\#9743}%
\begin{footnote}[901]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9743}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/3219}{\#3219}%
\begin{footnote}[902]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/3219}
%
\end{footnote},
by Kazuhiko Sakaguchi).

\item {} 
\sphinxAtStartPar
A new flag {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:flag.Fast-Name-Printing}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fast Name Printing}}}}} has been introduced. It changes the
algorithm used for allocating bound variable names for a faster but less
clever one
(\sphinxhref{https://github.com/coq/coq/pull/9078}{\#9078}%
\begin{footnote}[903]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9078}
%
\end{footnote}, by Pierre\sphinxhyphen{}Marie Pédrot).

\item {} 
\sphinxAtStartPar
Option \sphinxcode{\sphinxupquote{Typeclasses Axioms Are Instances}} (compatibility option
introduced in the previous version) is deprecated. Use {\hyperref[\detokenize{addendum/type-classes:coq:cmd.Declare-Instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare
Instance}}}}} for axioms which should be instances
(\sphinxhref{https://github.com/coq/coq/pull/8920}{\#8920}%
\begin{footnote}[904]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8920}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
Removed option \sphinxcode{\sphinxupquote{Printing Primitive Projection Compatibility}}
(\sphinxhref{https://github.com/coq/coq/pull/9306}{\#9306}%
\begin{footnote}[905]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9306}
%
\end{footnote}, by Gaëtan Gilbert).

\end{itemize}

\item {} 
\sphinxAtStartPar
Standard Library:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added \sphinxcode{\sphinxupquote{Bvector.BVeq}} that decides whether two \sphinxcode{\sphinxupquote{Bvector}}s are equal.
Added notations for \sphinxcode{\sphinxupquote{BVxor}}, \sphinxcode{\sphinxupquote{BVand}}, \sphinxcode{\sphinxupquote{BVor}}, \sphinxcode{\sphinxupquote{BVeq}} and \sphinxcode{\sphinxupquote{BVneg}}
(\sphinxhref{https://github.com/coq/coq/pull/8171}{\#8171}%
\begin{footnote}[906]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8171}
%
\end{footnote}, by Yishuai Li).

\item {} 
\sphinxAtStartPar
Added \sphinxcode{\sphinxupquote{ByteVector}} type that can convert to and from \sphinxcode{\sphinxupquote{string}}
(\sphinxhref{https://github.com/coq/coq/pull/8365}{\#8365}%
\begin{footnote}[907]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8365}
%
\end{footnote}, by Yishuai Li).

\item {} 
\sphinxAtStartPar
Added lemmas about monotonicity of \sphinxcode{\sphinxupquote{N.double}} and \sphinxcode{\sphinxupquote{N.succ\_double}}, and about
the upper bound of number represented by a vector.
Allowed implicit vector length argument in \sphinxcode{\sphinxupquote{Ndigits.Bv2N}}
(\sphinxhref{https://github.com/coq/coq/pull/8815}{\#8815}%
\begin{footnote}[908]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8815}
%
\end{footnote}, by Yishuai Li).

\item {} 
\sphinxAtStartPar
The prelude used to be automatically Exported and is now only
Imported. This should be relevant only when importing files which
don't use \sphinxcode{\sphinxupquote{\sphinxhyphen{}noinit}} into files which do
(\sphinxhref{https://github.com/coq/coq/pull/9013}{\#9013}%
\begin{footnote}[909]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9013}
%
\end{footnote}, by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
Added \sphinxcode{\sphinxupquote{Coq.Structures.OrderedTypeEx.String\_as\_OT}} to make strings an
ordered type, using lexical order
(\sphinxhref{https://github.com/coq/coq/pull/7221}{\#7221}%
\begin{footnote}[910]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/7221}
%
\end{footnote}, by Li Yao).

\item {} 
\sphinxAtStartPar
Added lemmas about \sphinxcode{\sphinxupquote{Z.testbit}}, \sphinxcode{\sphinxupquote{Z.ones}}, and \sphinxcode{\sphinxupquote{Z.modulo}}
(\sphinxhref{https://github.com/coq/coq/pull/9425}{\#9425}%
\begin{footnote}[911]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9425}
%
\end{footnote}, by Andres Erbsen).

\item {} 
\sphinxAtStartPar
Moved the \sphinxcode{\sphinxupquote{auto}} hints of the \sphinxcode{\sphinxupquote{FSet}} library into a new
\sphinxcode{\sphinxupquote{fset}} database
(\sphinxhref{https://github.com/coq/coq/pull/9725}{\#9725}%
\begin{footnote}[912]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9725}
%
\end{footnote}, by Frédéric Besson).

\item {} 
\sphinxAtStartPar
Added \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Structures}\DUrole{operator}{.}\DUrole{name}{EqualitiesFacts}\DUrole{operator}{.}\DUrole{name}{PairUsualDecidableTypeFull}}}
(\sphinxhref{https://github.com/coq/coq/pull/9984}{\#9984}%
\begin{footnote}[913]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9984}
%
\end{footnote},
by Jean\sphinxhyphen{}Christophe Léchenet and Oliver Nash).

\end{itemize}

\item {} 
\sphinxAtStartPar
Some error messages that show problems with a pair of non\sphinxhyphen{}matching
values will now highlight the differences
(\sphinxhref{https://github.com/coq/coq/pull/8669}{\#8669}%
\begin{footnote}[914]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8669}
%
\end{footnote}, by Jim Fehrle).

\item {} 
\sphinxAtStartPar
Changelog has been moved from a specific file \sphinxcode{\sphinxupquote{CHANGES.md}} to the
reference manual; former Credits chapter of the reference manual has
been split in two parts: a History chapter which was enriched with
additional historical information about Coq versions 1 to 5, and a
Changes chapter which was enriched with the content formerly in
\sphinxcode{\sphinxupquote{CHANGES.md}} and \sphinxcode{\sphinxupquote{COMPATIBILITY}}
(\sphinxhref{https://github.com/coq/coq/pull/9133}{\#9133}%
\begin{footnote}[915]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9133}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/9668}{\#9668}%
\begin{footnote}[916]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9668}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/9939}{\#9939}%
\begin{footnote}[917]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9939}
%
\end{footnote},
\sphinxhref{https://github.com/coq/coq/pull/9964}{\#9964}%
\begin{footnote}[918]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9964}
%
\end{footnote},
and \sphinxhref{https://github.com/coq/coq/pull/10085}{\#10085}%
\begin{footnote}[919]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10085}
%
\end{footnote},
by Théo Zimmermann,
with help and ideas from Emilio Jesús Gallego Arias, Gaëtan
Gilbert, Clément Pit\sphinxhyphen{}Claudel, Matthieu Sozeau, and Enrico Tassi).

\end{itemize}


\paragraph{Changes in 8.10+beta2}
\label{\detokenize{changes:changes-in-8-10-beta2}}
\sphinxAtStartPar
Many bug fixes and documentation improvements, in particular:

\sphinxAtStartPar
\sphinxstylestrong{Tactics}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Make the {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}} tactic work together with
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}} and equality in \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}. This,
in particular, makes {\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}} compatible with the HoTT
library \sphinxurl{https://github.com/HoTT/HoTT}
(\sphinxhref{https://github.com/coq/coq/pull/10205}{\#10205}%
\begin{footnote}[920]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10205}
%
\end{footnote},
by Andreas Lynge, review by Pierre\sphinxhyphen{}Marie Pédrot and Matthieu Sozeau).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{SSReflect}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Make the \sphinxcode{\sphinxupquote{case E: t}} tactic work together with
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}} and equality in \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}.
This makes {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.case-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}} compatible with the HoTT
library \sphinxurl{https://github.com/HoTT/HoTT}
(\sphinxhref{https://github.com/coq/coq/pull/10302}{\#10302}%
\begin{footnote}[921]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10302}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10301}{\#10301}%
\begin{footnote}[922]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10301}
%
\end{footnote},
by Andreas Lynge, review by Enrico Tassi)

\item {} 
\sphinxAtStartPar
Make the \sphinxcode{\sphinxupquote{rewrite /t}} tactic work together with
{\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.Universe-Polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}}.
This makes {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.rewrite-(ssreflect)}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} compatible with the HoTT
library \sphinxurl{https://github.com/HoTT/HoTT}
(\sphinxhref{https://github.com/coq/coq/pull/10305}{\#10305}%
\begin{footnote}[923]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10305}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9336}{\#9336}%
\begin{footnote}[924]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9336}
%
\end{footnote},
by Andreas Lynge, review by Enrico Tassi)

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{CoqIDE}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix CoqIDE instability on Windows after the update to gtk3
(\sphinxhref{https://github.com/coq/coq/pull/10360}{\#10360}%
\begin{footnote}[925]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10360}
%
\end{footnote}, by Michael Soegtrop,
closes \sphinxhref{https://github.com/coq/coq/issues/9885}{\#9885}%
\begin{footnote}[926]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9885}
%
\end{footnote}).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Miscellaneous}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Proof General can now display Coq\sphinxhyphen{}generated diffs between proof steps
in color
(\sphinxhref{https://github.com/coq/coq/pull/10019}{\#10019}%
\begin{footnote}[927]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10019}
%
\end{footnote} and
(in Proof General) \sphinxhref{https://github.com/ProofGeneral/PG/pull/421}{\#421}%
\begin{footnote}[928]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/ProofGeneral/PG/pull/421}
%
\end{footnote},
by Jim Fehrle).

\end{itemize}


\paragraph{Changes in 8.10+beta3}
\label{\detokenize{changes:changes-in-8-10-beta3}}
\sphinxAtStartPar
\sphinxstylestrong{Kernel}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix soundness issue with template polymorphism (\sphinxhref{https://github.com/coq/coq/issues/9294}{\#9294}%
\begin{footnote}[929]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9294}
%
\end{footnote}).

\sphinxAtStartPar
Declarations of template\sphinxhyphen{}polymorphic inductive types ignored the
provenance of the universes they were abstracting on and did not
detect if they should be greater or equal to \(\Set\) in
general. Previous universes and universes introduced by the inductive
definition could have constraints that prevented their instantiation
with e.g. \(\Prop\), resulting in unsound instantiations later. The
implemented fix only allows abstraction over universes introduced by
the inductive declaration, and properly records all their constraints
by making them by default only \(>= \Prop\). It is also checked
that a template polymorphic inductive actually is polymorphic on at
least one universe.

\sphinxAtStartPar
This prevents inductive declarations in sections to be universe
polymorphic over section parameters. For a backward compatible fix,
simply hoist the inductive definition out of the section.
An alternative is to declare the inductive as universe\sphinxhyphen{}polymorphic and
cumulative in a universe\sphinxhyphen{}polymorphic section: all universes and
constraints will be properly gathered in this case.
See {\hyperref[\detokenize{language/core/inductive:template-polymorphism}]{\sphinxcrossref{\DUrole{std,std-ref}{Template polymorphism}}}} for a detailed exposition of the
rules governing template\sphinxhyphen{}polymorphic types.

\sphinxAtStartPar
To help users incrementally fix this issue, a command line option
\sphinxcode{\sphinxupquote{\sphinxhyphen{}no\sphinxhyphen{}template\sphinxhyphen{}check}} and a global flag \sphinxcode{\sphinxupquote{Template Check}} are
available to selectively disable the new check. Use at your own risk.

\sphinxAtStartPar
(\sphinxhref{https://github.com/coq/coq/pull/9918}{\#9918}%
\begin{footnote}[930]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9918}
%
\end{footnote}, by Matthieu Sozeau
and Maxime Dénès).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{User messages}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Improve the ambiguous paths warning to indicate which path is ambiguous with
new one
(\sphinxhref{https://github.com/coq/coq/pull/10336}{\#10336}%
\begin{footnote}[931]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10336}
%
\end{footnote},
closes \sphinxhref{https://github.com/coq/coq/issues/3219}{\#3219}%
\begin{footnote}[932]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/3219}
%
\end{footnote},
by Kazuhiko Sakaguchi).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Extraction}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix extraction to OCaml of primitive machine integers;
see {\hyperref[\detokenize{language/core/primitive:primitive-integers}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Integers}}}}
(\sphinxhref{https://github.com/coq/coq/pull/10430}{\#10430}%
\begin{footnote}[933]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10430}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10361}{\#10361}%
\begin{footnote}[934]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10361}
%
\end{footnote},
by Vincent Laporte).

\item {} 
\sphinxAtStartPar
Fix a printing bug of OCaml extraction on dependent record projections, which
produced improper \sphinxcode{\sphinxupquote{assert false}}. This change makes the OCaml extractor
internally inline record projections by default; thus the monolithic OCaml
extraction ({\hyperref[\detokenize{addendum/extraction:coq:cmd.Extraction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction}}}}} and {\hyperref[\detokenize{addendum/extraction:coq:cmd.Recursive-Extraction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Recursive Extraction}}}}}) does not
produce record projection constants anymore except for record projections
explicitly instructed to extract, and records declared in opaque modules
(\sphinxhref{https://github.com/coq/coq/pull/10577}{\#10577}%
\begin{footnote}[935]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10577}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/7348}{\#7348}%
\begin{footnote}[936]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/7348}
%
\end{footnote},
by Kazuhiko Sakaguchi).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Standard library}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added \sphinxcode{\sphinxupquote{splitat}} function and lemmas about \sphinxcode{\sphinxupquote{splitat}} and \sphinxcode{\sphinxupquote{uncons}}
(\sphinxhref{https://github.com/coq/coq/pull/9379}{\#9379}%
\begin{footnote}[937]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/9379}
%
\end{footnote},
by Yishuai Li, with help of Konstantinos Kallas,
follow\sphinxhyphen{}up of \sphinxhref{https://github.com/coq/coq/pull/8365}{\#8365}%
\begin{footnote}[938]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/8365}
%
\end{footnote},
which added \sphinxcode{\sphinxupquote{uncons}} in 8.10+beta1).

\end{itemize}


\paragraph{Changes in 8.10.0}
\label{\detokenize{changes:changes-in-8-10-0}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Micromega tactics ({\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}}, {\hyperref[\detokenize{addendum/micromega:coq:tacn.nia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nia}}}}}, etc) are no longer confused by
primitive projections (\sphinxhref{https://github.com/coq/coq/pull/10806}{\#10806}%
\begin{footnote}[939]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10806}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9512}{\#9512}%
\begin{footnote}[940]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9512}
%
\end{footnote}
by Vincent Laporte).

\end{itemize}


\paragraph{Changes in 8.10.1}
\label{\detokenize{changes:changes-in-8-10-1}}
\sphinxAtStartPar
A few bug fixes and documentation improvements, in particular:

\sphinxAtStartPar
\sphinxstylestrong{Kernel}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix proof of False when using \(\SProp\) (incorrect De Bruijn handling
when inferring the relevance mark of a function) (\sphinxhref{https://github.com/coq/coq/pull/10904}{\#10904}%
\begin{footnote}[941]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10904}
%
\end{footnote}, by Pierre\sphinxhyphen{}Marie Pédrot).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactics}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix an anomaly when unsolved evar in {\hyperref[\detokenize{addendum/ring:coq:cmd.Add-Ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add Ring}}}}}
(\sphinxhref{https://github.com/coq/coq/pull/10891}{\#10891}%
\begin{footnote}[942]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10891}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/9851}{\#9851}%
\begin{footnote}[943]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/9851}
%
\end{footnote},
by Gaëtan Gilbert).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Tactic language}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix Ltac regression in binding free names in uconstr
(\sphinxhref{https://github.com/coq/coq/pull/10899}{\#10899}%
\begin{footnote}[944]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10899}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10894}{\#10894}%
\begin{footnote}[945]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10894}
%
\end{footnote},
by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{CoqIDE}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix handling of unicode input before space
(\sphinxhref{https://github.com/coq/coq/pull/10852}{\#10852}%
\begin{footnote}[946]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10852}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/10842}{\#10842}%
\begin{footnote}[947]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10842}
%
\end{footnote},
by Arthur Charguéraud).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Extraction}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix custom extraction of inductives to JSON
(\sphinxhref{https://github.com/coq/coq/pull/10897}{\#10897}%
\begin{footnote}[948]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/10897}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/4741}{\#4741}%
\begin{footnote}[949]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/4741}
%
\end{footnote},
by Helge Bahmann).

\end{itemize}


\paragraph{Changes in 8.10.2}
\label{\detokenize{changes:changes-in-8-10-2}}
\sphinxAtStartPar
\sphinxstylestrong{Kernel}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fixed a critical bug of template polymorphism and nonlinear universes
(\sphinxhref{https://github.com/coq/coq/pull/11128}{\#11128}%
\begin{footnote}[950]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11128}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11039}{\#11039}%
\begin{footnote}[951]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11039}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
Fixed an anomaly “Uncaught exception Constr.DestKO” on \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Inductive}}}
(\sphinxhref{https://github.com/coq/coq/pull/11052}{\#11052}%
\begin{footnote}[952]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11052}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11048}{\#11048}%
\begin{footnote}[953]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11048}
%
\end{footnote},
by Gaëtan Gilbert).

\item {} 
\sphinxAtStartPar
Fixed an anomaly “not enough abstractions in fix body”
(\sphinxhref{https://github.com/coq/coq/pull/11014}{\#11014}%
\begin{footnote}[954]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11014}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/8459}{\#8459}%
\begin{footnote}[955]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/8459}
%
\end{footnote},
by Gaëtan Gilbert).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Notations}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fixed an 8.10 regression related to the printing of coercions associated with notations
(\sphinxhref{https://github.com/coq/coq/pull/11090}{\#11090}%
\begin{footnote}[956]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11090}
%
\end{footnote},
fixes \sphinxhref{https://github.com/coq/coq/issues/11033}{\#11033}%
\begin{footnote}[957]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11033}
%
\end{footnote}, by Hugo Herbelin).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{CoqIDE}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fixed uneven dimensions of CoqIDE panels when window has been resized
(\sphinxhref{https://github.com/coq/coq/pull/11070}{\#11070}%
\begin{footnote}[958]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11070}
%
\end{footnote},
fixes 8.10\sphinxhyphen{}regression \sphinxhref{https://github.com/coq/coq/issues/10956}{\#10956}%
\begin{footnote}[959]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10956}
%
\end{footnote},
by Guillaume Melquiond).

\item {} 
\sphinxAtStartPar
Do not include final stops in queries
(\sphinxhref{https://github.com/coq/coq/pull/11069}{\#11069}%
\begin{footnote}[960]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11069}
%
\end{footnote},
fixes 8.10\sphinxhyphen{}regression \sphinxhref{https://github.com/coq/coq/issues/11058}{\#11058}%
\begin{footnote}[961]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/11058}
%
\end{footnote},
by Guillaume Melquiond).

\end{itemize}

\sphinxAtStartPar
\sphinxstylestrong{Infrastructure and dependencies}
\begin{itemize}
\item {} 
\sphinxAtStartPar
Enable building of executables when they are running
(\sphinxhref{https://github.com/coq/coq/pull/11000}{\#11000}%
\begin{footnote}[962]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/pull/11000}
%
\end{footnote},
fixes 8.9\sphinxhyphen{}regression \sphinxhref{https://github.com/coq/coq/issues/10728}{\#10728}%
\begin{footnote}[963]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/coq/coq/issues/10728}
%
\end{footnote},
by Gaëtan Gilbert).

\end{itemize}


\subsubsection{Version 8.9}
\label{\detokenize{changes:version-8-9}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id940}}
\sphinxAtStartPar
Coq version 8.9 contains the result of refinements and stabilization
of features and deprecations or removals of deprecated features,
cleanups of the internals of the system and API along with a few new
features. This release includes many user\sphinxhyphen{}visible changes, including
deprecations that are documented in the next subsection and new features that
are documented in the reference manual. Here are the most important
changes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Kernel: mutually recursive records are now supported, by Pierre\sphinxhyphen{}Marie
Pédrot.

\item {} 
\sphinxAtStartPar
Notations:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Support for autonomous grammars of terms called “custom entries”, by
Hugo Herbelin (see Section {\hyperref[\detokenize{user-extensions/syntax-extensions:custom-entries}]{\sphinxcrossref{\DUrole{std,std-ref}{Custom entries}}}} of the reference
manual).

\item {} 
\sphinxAtStartPar
Deprecated notations of the standard library will be removed in the
next version of Coq, see the next subsection for a script to
ease porting, by Jason Gross and Jean\sphinxhyphen{}Christophe Léchenet.

\item {} 
\sphinxAtStartPar
Added the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.Number-Notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Number Notation}}}}} command for registering decimal
numeral notations for custom types, by Daniel de Rauglaudre, Pierre
Letouzey and Jason Gross.

\end{itemize}

\item {} 
\sphinxAtStartPar
Tactics: Introduction tactics {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}/{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}} on a goal that is an
existential variable now force a refinement of the goal into a
dependent product rather than failing, by Hugo Herbelin.

\item {} 
\sphinxAtStartPar
Decision procedures: deprecation of tactic \sphinxcode{\sphinxupquote{romega}} in favor of
{\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} and removal of \sphinxcode{\sphinxupquote{fourier}}, replaced by {\hyperref[\detokenize{addendum/micromega:coq:tacn.lra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lra}}}}} which
subsumes it, by Frédéric Besson, Maxime Dénès, Vincent Laporte and
Laurent Théry.

\item {} 
\sphinxAtStartPar
Proof language: focusing bracket \sphinxcode{\sphinxupquote{\{}} now supports named
{\hyperref[\detokenize{proofs/writing-proofs/proof-mode:curly-braces}]{\sphinxcrossref{\DUrole{std,std-ref}{goals}}}}, e.g. \sphinxcode{\sphinxupquote{{[}x{]}:\{}} will focus
on a goal (existential variable) named \sphinxcode{\sphinxupquote{x}}, by Théo Zimmermann.

\item {} 
\sphinxAtStartPar
SSReflect: the implementation of delayed clear was simplified by
Enrico Tassi: the variables are always renamed using inaccessible
names when the clear switch is processed and finally cleared at the
end of the intro pattern. In addition to that, the use\sphinxhyphen{}and\sphinxhyphen{}discard flag
\sphinxcode{\sphinxupquote{\{\}}} typical of rewrite rules can now be also applied to views,
e.g. \sphinxcode{\sphinxupquote{=> \{\}/v}} applies \sphinxcode{\sphinxupquote{v}} and then clears \sphinxcode{\sphinxupquote{v}}. See Section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}.

\item {} 
\sphinxAtStartPar
Vernacular:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Experimental support for {\hyperref[\detokenize{language/core/basic:term-attribute}]{\sphinxtermref{\DUrole{xref,std,std-term}{attributes}}}} on
commands, by Vincent Laporte, as in \sphinxcode{\sphinxupquote{\#{[}local{]} Lemma foo : bar.}}
Tactics and tactic notations now support the \sphinxcode{\sphinxupquote{deprecated}}
attribute.

\item {} 
\sphinxAtStartPar
Removed deprecated commands \sphinxcode{\sphinxupquote{Arguments Scope}} and \sphinxcode{\sphinxupquote{Implicit
Arguments}} in favor of {\hyperref[\detokenize{language/extensions/arguments-command:coq:cmd.Arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}}, with the help of Jasper Hugunin.

\item {} 
\sphinxAtStartPar
New flag {\hyperref[\detokenize{language/core/inductive:coq:flag.Uniform-Inductive-Parameters}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Uniform Inductive Parameters}}}}} by Jasper Hugunin to
avoid repeating uniform parameters in constructor declarations.

\item {} 
\sphinxAtStartPar
New commands {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Variables}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Variables}}}}} and {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Hint-Constants}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Constants}}}}}, by
Matthieu Sozeau, for controlling the opacity status of variables and
constants in hint databases. It is recommended to always use these
commands after creating a hint database with {\hyperref[\detokenize{proofs/automatic-tactics/auto:coq:cmd.Create-HintDb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Create HintDb}}}}}.

\item {} 
\sphinxAtStartPar
Multiple sections with the same name are now allowed, by Jasper
Hugunin.

\end{itemize}

\item {} 
\sphinxAtStartPar
Library: additions and changes in the \sphinxcode{\sphinxupquote{VectorDef}}, \sphinxcode{\sphinxupquote{Ascii}}, and
\sphinxcode{\sphinxupquote{String}} libraries. Syntax notations are now available only when using
\sphinxcode{\sphinxupquote{Import}} of libraries and not merely \sphinxcode{\sphinxupquote{Require}}, by various
contributors (source of incompatibility, see the next subsection for details).

\item {} 
\sphinxAtStartPar
Toplevels: \sphinxcode{\sphinxupquote{coqtop}} and \sphinxcode{\sphinxupquote{coqide}} can now display diffs between proof
steps in color, using the {\hyperref[\detokenize{proofs/writing-proofs/proof-mode:coq:opt.Diffs}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Diffs}}}}} option, by Jim Fehrle.

\item {} 
\sphinxAtStartPar
Documentation: we integrated a large number of fixes to the new Sphinx
documentation by various contributors, coordinated by Clément
Pit\sphinxhyphen{}Claudel and Théo Zimmermann.

\item {} 
\sphinxAtStartPar
Tools: removed the \sphinxcode{\sphinxupquote{gallina}} utility and the homebrewed \sphinxcode{\sphinxupquote{Emacs}} mode.

\item {} 
\sphinxAtStartPar
Packaging: as in Coq 8.8.2, the Windows installer now includes many
more external packages that can be individually selected for
installation, by Michael Soegtrop.

\end{itemize}

\sphinxAtStartPar
Version 8.9 also comes with a bunch of smaller\sphinxhyphen{}scale changes and
improvements regarding the different components of the system.  Most
important ones are documented in the next subsection file.

\sphinxAtStartPar
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 and a plugin development tutorial kept in sync with Coq was
introduced by Yves Bertot \sphinxurl{http://github.com/ybertot/plugin\_tutorials}.
The new \sphinxcode{\sphinxupquote{dev/doc/critical\sphinxhyphen{}bugs}} file documents the known critical bugs
of Coq and affected releases.

\sphinxAtStartPar
The efficiency of the whole system has seen improvements thanks to
contributions from Gaëtan Gilbert, Pierre\sphinxhyphen{}Marie Pédrot, and Maxime Dénès.

\sphinxAtStartPar
Maxime Dénès, Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop, Théo Zimmermann worked on maintaining and improving the
continuous integration system.

\sphinxAtStartPar
The OPAM repository for 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/}.

\sphinxAtStartPar
The 54 contributors for this version are Léo Andrès, Rin Arakaki,
Benjamin Barenblat, Langston Barrett, Siddharth Bhat, Martin Bodin,
Simon Boulier, Timothy Bourke, Joachim Breitner, Tej Chajed, Arthur
Charguéraud, Pierre Courtieu, Maxime Dénès, Andres Erbsen, Jim Fehrle,
Julien Forest, Emilio Jesus Gallego Arias, Gaëtan Gilbert, Matěj
Grabovský, Jason Gross, Samuel Gruetter, Armaël Guéneau, Hugo Herbelin,
Jasper Hugunin, Ralf Jung, Sam Pablo Kuper, Ambroise Lafont, Leonidas
Lampropoulos, Vincent Laporte, Peter LeFanu Lumsdaine, Pierre Letouzey,
Jean\sphinxhyphen{}Christophe Léchenet, Nick Lewycky, Yishuai Li, Sven M. Hallberg,
Assia Mahboubi, Cyprien Mangin, Guillaume Melquiond, Perry E. Metzger,
Clément Pit\sphinxhyphen{}Claudel, Pierre\sphinxhyphen{}Marie Pédrot, Daniel R. Grayson, Kazuhiko
Sakaguchi, Michael Soegtrop, Matthieu Sozeau, Paul Steckler, Enrico
Tassi, Laurent Théry, Anton Trunov, whitequark, Théo Winterhalter,
Zeimer, Beta Ziliani, Théo Zimmermann.

\sphinxAtStartPar
Many power users helped to improve the design of the new features via
the issue and pull request system, the Coq development mailing list or
the \sphinxhref{mailto:coq-club@inria.fr}{coq\sphinxhyphen{}club@inria.fr} mailing list. It would be impossible to mention
exhaustively the names of everybody who to some extent influenced the
development.

\sphinxAtStartPar
Version 8.9 is the fourth release of Coq developed on a time\sphinxhyphen{}based
development cycle. Its development spanned 7 months from the release of
Coq 8.8. The development moved to a decentralized merging process
during this cycle. Guillaume Melquiond was in charge of the release
process and is the maintainer of this release. This release is the
result of \textasciitilde{}2,000 commits and \textasciitilde{}500 PRs merged, closing 75+ issues.

\sphinxAtStartPar
The Coq development team welcomed Vincent Laporte, a new Coq
engineer working with Maxime Dénès in the Coq consortium.

\begin{DUlineblock}{0em}
\item[] Paris, November 2018,
\item[] Matthieu Sozeau for the Coq development team
\item[] 
\end{DUlineblock}


\paragraph{Details of changes in 8.9+beta1}
\label{\detokenize{changes:details-of-changes-in-8-9-beta1}}
\sphinxAtStartPar
Kernel
\begin{itemize}
\item {} 
\sphinxAtStartPar
Mutually defined records are now supported.

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
New support for autonomous grammars of terms, called "custom
entries" (see chapter "Syntax extensions" of the reference manual).

\item {} 
\sphinxAtStartPar
Deprecated compatibility notations will actually be removed in the
next version of Coq.  Uses of these notations are generally easy to
fix thanks to the hint contained in the deprecation warnings. For
projects that require more than a handful of such fixes, there is \sphinxhref{https://gist.github.com/JasonGross/9770653967de3679d131c59d42de6d17\#file-replace-notations-py}{a
script}%
\begin{footnote}[964]\sphinxAtStartFootnote
\sphinxnolinkurl{https://gist.github.com/JasonGross/9770653967de3679d131c59d42de6d17\#file-replace-notations-py}
%
\end{footnote}
that will do it automatically, using the output of \sphinxcode{\sphinxupquote{coqc}}. The script
contains documentation on its usage in a comment at the top.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added toplevel goal selector \sphinxcode{\sphinxupquote{!}} which expects a single focused goal.
Use with \sphinxcode{\sphinxupquote{Set Default Goal Selector}} to force focusing before tactics
are called.

\item {} 
\sphinxAtStartPar
The undocumented "nameless" forms \sphinxcode{\sphinxupquote{fix N}}, \sphinxcode{\sphinxupquote{cofix}} that were
deprecated in 8.8 have been removed from Ltac's syntax; please use
\sphinxcode{\sphinxupquote{fix ident N/cofix ident}} to explicitly name the (co)fixpoint
hypothesis to be introduced.

\item {} 
\sphinxAtStartPar
Introduction tactics \sphinxcode{\sphinxupquote{intro}}/\sphinxcode{\sphinxupquote{intros}} on a goal that is an
existential variable now force a refinement of the goal into a
dependent product rather than failing.

\item {} 
\sphinxAtStartPar
Support for \sphinxcode{\sphinxupquote{fix}}/\sphinxcode{\sphinxupquote{cofix}} added in Ltac \sphinxcode{\sphinxupquote{match}} and \sphinxcode{\sphinxupquote{lazymatch}}.

\item {} 
\sphinxAtStartPar
Ltac backtraces now include trace information about tactics
called by OCaml\sphinxhyphen{}defined tactics.

\item {} 
\sphinxAtStartPar
Option \sphinxcode{\sphinxupquote{Ltac Debug}} now applies also to terms built using Ltac functions.

\item {} 
\sphinxAtStartPar
Deprecated the \sphinxcode{\sphinxupquote{Implicit Tactic}} family of commands.

\item {} 
\sphinxAtStartPar
The default program obligation tactic uses a bounded proof search
instead of an unbounded and potentially non\sphinxhyphen{}terminating one now
(source of incompatibility).

\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{simple apply}} tactic now respects the \sphinxcode{\sphinxupquote{Opaque}} flag when called from
Ltac (\sphinxcode{\sphinxupquote{auto}} still does not respect it).

\item {} 
\sphinxAtStartPar
Tactic \sphinxcode{\sphinxupquote{constr\_eq}} now adds universe constraints needed for the
identity to the context (it used to ignore them). New tactic
\sphinxcode{\sphinxupquote{constr\_eq\_strict}} checks that the required constraints already hold
without adding new ones. Preexisting tactic \sphinxcode{\sphinxupquote{constr\_eq\_nounivs}} can
still be used if you really want to ignore universe constraints.

\item {} 
\sphinxAtStartPar
Tactics and tactic notations now understand the \sphinxcode{\sphinxupquote{deprecated}} attribute.

\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{fourier}} tactic has been removed. Please now use \sphinxcode{\sphinxupquote{lra}} instead. You
may need to add \sphinxcode{\sphinxupquote{Require Import Lra}} to your developments. For compatibility,
we now define \sphinxcode{\sphinxupquote{fourier}} as a deprecated alias of \sphinxcode{\sphinxupquote{lra}}.

\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{romega}} tactics have been deprecated; please use \sphinxcode{\sphinxupquote{lia}} instead.

\end{itemize}

\sphinxAtStartPar
Focusing
\begin{itemize}
\item {} 
\sphinxAtStartPar
Focusing bracket \sphinxcode{\sphinxupquote{\{}} now supports named goal selectors,
e.g. \sphinxcode{\sphinxupquote{{[}x{]}: \{}} will focus on a goal (existential variable) named \sphinxcode{\sphinxupquote{x}}.
As usual, unfocus with \sphinxcode{\sphinxupquote{\}}} once the subgoal is fully solved.

\end{itemize}

\sphinxAtStartPar
Specification language
\begin{itemize}
\item {} 
\sphinxAtStartPar
A fix to unification (which was sensitive to the ascii name of
variables) may occasionally change type inference in incompatible
ways, especially regarding the inference of the return clause of \sphinxcode{\sphinxupquote{match}}.

\end{itemize}

\sphinxAtStartPar
Standard Library
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added \sphinxcode{\sphinxupquote{Ascii.eqb}} and \sphinxcode{\sphinxupquote{String.eqb}} and the \sphinxcode{\sphinxupquote{=?}} notation for them,
and proved some lemmas about them.  Note that this might cause
incompatibilities if you have, e.g., \sphinxcode{\sphinxupquote{string\_scope}} and \sphinxcode{\sphinxupquote{Z\_scope}} both
open with \sphinxcode{\sphinxupquote{string\_scope}} on top, and expect \sphinxcode{\sphinxupquote{=?}} to refer to \sphinxcode{\sphinxupquote{Z.eqb}}.
Solution: wrap \sphinxcode{\sphinxupquote{\_ =? \_}} in \sphinxcode{\sphinxupquote{(\_ =? \_)\%Z}} (or whichever scope you
want).

\item {} 
\sphinxAtStartPar
Added \sphinxcode{\sphinxupquote{Ndigits.N2Bv\_sized}}, and proved some lemmas about it.
Deprecated \sphinxcode{\sphinxupquote{Ndigits.N2Bv\_gen}}.

\item {} 
\sphinxAtStartPar
The scopes \sphinxcode{\sphinxupquote{int\_scope}} and \sphinxcode{\sphinxupquote{uint\_scope}} have been renamed to
\sphinxcode{\sphinxupquote{dec\_int\_scope}} and \sphinxcode{\sphinxupquote{dec\_uint\_scope}}, to clash less with ssreflect
and other packages.  They are still delimited by \sphinxcode{\sphinxupquote{\%int}} and \sphinxcode{\sphinxupquote{\%uint}}.

\item {} 
\sphinxAtStartPar
Syntax notations for \sphinxcode{\sphinxupquote{string}}, \sphinxcode{\sphinxupquote{ascii}}, \sphinxcode{\sphinxupquote{Z}}, \sphinxcode{\sphinxupquote{positive}}, \sphinxcode{\sphinxupquote{N}}, \sphinxcode{\sphinxupquote{R}},
and \sphinxcode{\sphinxupquote{int31}} are no longer available merely by {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.Require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}}ing the files
that define the inductives.  You must {\hyperref[\detokenize{language/core/modules:coq:cmd.Import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} \sphinxcode{\sphinxupquote{Coq.Strings.String.StringSyntax}}
(after \sphinxcode{\sphinxupquote{Require}} \sphinxcode{\sphinxupquote{Coq.Strings.String}}), \sphinxcode{\sphinxupquote{Coq.Strings.Ascii.AsciiSyntax}} (after
\sphinxcode{\sphinxupquote{Require}} \sphinxcode{\sphinxupquote{Coq.Strings.Ascii}}), \sphinxcode{\sphinxupquote{Coq.ZArith.BinIntDef}}, \sphinxcode{\sphinxupquote{Coq.PArith.BinPosDef}},
\sphinxcode{\sphinxupquote{Coq.NArith.BinNatDef}}, \sphinxcode{\sphinxupquote{Coq.Reals.Rdefinitions}}, and
\sphinxcode{\sphinxupquote{Coq.Numbers.Cyclic.Int31.Int31}}, respectively, to be able to use
these notations.  Note that passing \sphinxcode{\sphinxupquote{\sphinxhyphen{}compat 8.8}} or issuing
\sphinxcode{\sphinxupquote{Require Import Coq.Compat.Coq88}} will make these notations
available.  Users wishing to port their developments automatically
may download \sphinxcode{\sphinxupquote{fix.py}} from
\sphinxurl{https://gist.github.com/JasonGross/5d4558edf8f5c2c548a3d96c17820169}
and run a command like \sphinxcode{\sphinxupquote{while true; do make \sphinxhyphen{}Okj 2>\&1 |
/path/to/fix.py; done}} and get a cup of coffee.  (This command must
be manually interrupted once the build finishes all the way though.
Note also that this method is not fail\sphinxhyphen{}proof; you may have to adjust
some scopes if you were relying on string notations not being
available even when \sphinxcode{\sphinxupquote{string\_scope}} was open.)

\item {} 
\sphinxAtStartPar
Numeral syntax for \sphinxcode{\sphinxupquote{nat}} is no longer available without loading the
entire prelude (\sphinxcode{\sphinxupquote{Require Import Coq.Init.Prelude}}).  This only
impacts users running Coq without the init library (\sphinxcode{\sphinxupquote{\sphinxhyphen{}nois}} or
\sphinxcode{\sphinxupquote{\sphinxhyphen{}noinit}}) and also issuing \sphinxcode{\sphinxupquote{Require Import Coq.Init.Datatypes}}.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Coq\_makefile lets one override or extend the following variables from
the command line: \sphinxcode{\sphinxupquote{COQFLAGS}}, \sphinxcode{\sphinxupquote{COQCHKFLAGS}}, \sphinxcode{\sphinxupquote{COQDOCFLAGS}}.
\sphinxcode{\sphinxupquote{COQFLAGS}} is now entirely separate from \sphinxcode{\sphinxupquote{COQLIBS}}, so in custom Makefiles
\sphinxcode{\sphinxupquote{\$(COQFLAGS)}} should be replaced by \sphinxcode{\sphinxupquote{\$(COQFLAGS) \$(COQLIBS)}}.

\item {} 
\sphinxAtStartPar
Removed the \sphinxcode{\sphinxupquote{gallina}} utility (extracts specification from Coq vernacular files).
If you would like to maintain this tool externally, please contact us.

\item {} 
\sphinxAtStartPar
Removed the Emacs modes distributed with Coq. You are advised to
use \sphinxhref{https://proofgeneral.github.io/}{Proof\sphinxhyphen{}General}%
\begin{footnote}[965]\sphinxAtStartFootnote
\sphinxnolinkurl{https://proofgeneral.github.io/}
%
\end{footnote} (and optionally
\sphinxhref{https://github.com/cpitclaudel/company-coq}{Company\sphinxhyphen{}Coq}%
\begin{footnote}[966]\sphinxAtStartFootnote
\sphinxnolinkurl{https://github.com/cpitclaudel/company-coq}
%
\end{footnote}) instead.
If your use case is not covered by these alternative Emacs modes,
please open an issue. We can help set up external maintenance as part
of Proof\sphinxhyphen{}General, or independently as part of coq\sphinxhyphen{}community.

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
Removed deprecated commands \sphinxcode{\sphinxupquote{Arguments Scope}} and \sphinxcode{\sphinxupquote{Implicit Arguments}}
(not the option). Use the \sphinxcode{\sphinxupquote{Arguments}} command instead.

\item {} 
\sphinxAtStartPar
Nested proofs may be enabled through the option \sphinxcode{\sphinxupquote{Nested Proofs Allowed}}.
By default, they are disabled and produce an error. The deprecation
warning which used to occur when using nested proofs has been removed.

\item {} 
\sphinxAtStartPar
Added option \sphinxcode{\sphinxupquote{Uniform Inductive Parameters}} which abstracts over parameters
before typechecking constructors, allowing to write for example
\sphinxcode{\sphinxupquote{Inductive list (A : Type) := nil : list | cons : A \sphinxhyphen{}> list \sphinxhyphen{}> list.}}

\item {} 
\sphinxAtStartPar
New \sphinxcode{\sphinxupquote{Set Hint Variables/Constants Opaque/Transparent}} commands for setting
globally the opacity flag of variables and constants in hint databases,
overriding the opacity setting of the hint database.

\item {} 
\sphinxAtStartPar
Added generic syntax for "attributes", as in:
\sphinxcode{\sphinxupquote{\#{[}local{]} Lemma foo : bar.}}

\item {} 
\sphinxAtStartPar
Added the \sphinxcode{\sphinxupquote{Numeral Notation}} command for registering decimal numeral
notations for custom types

\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Set SsrHave NoTCResolution}} command no longer has special global
scope. If you want the previous behavior, use \sphinxcode{\sphinxupquote{Global Set SsrHave
NoTCResolution}}.

\item {} 
\sphinxAtStartPar
Multiple sections with the same name are allowed.

\end{itemize}

\sphinxAtStartPar
Coq binaries and process model
\begin{itemize}
\item {} 
\sphinxAtStartPar
Before 8.9, Coq distributed a single \sphinxcode{\sphinxupquote{coqtop}} binary and a set of
dynamically loadable plugins that used to take over the main loop
for tasks such as IDE language server or parallel proof checking.

\sphinxAtStartPar
These plugins have been turned into full\sphinxhyphen{}fledged binaries so each
different process has associated a particular binary now, in
particular \sphinxcode{\sphinxupquote{coqidetop}} is the CoqIDE language server, and
\sphinxcode{\sphinxupquote{coq\{proof,tactic,query\}worker}} are in charge of task\sphinxhyphen{}specific and
parallel proof checking.

\end{itemize}

\sphinxAtStartPar
SSReflect
\begin{itemize}
\item {} 
\sphinxAtStartPar
The implementation of delayed clear switches in intro patterns
is now simpler to explain:
\begin{enumerate}
\sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}%
\item {} 
\sphinxAtStartPar
The immediate effect of a clear switch like \sphinxcode{\sphinxupquote{\{x\}}} is to rename the
variable \sphinxcode{\sphinxupquote{x}} to \sphinxcode{\sphinxupquote{\_x\_}} (i.e. a reserved identifier that cannot be mentioned
explicitly)

\item {} 
\sphinxAtStartPar
The delayed effect of \sphinxcode{\sphinxupquote{\{x\}}} is that \sphinxcode{\sphinxupquote{\_x\_}} is cleared at the end of the intro
pattern

\item {} 
\sphinxAtStartPar
A clear switch immediately before a view application like \sphinxcode{\sphinxupquote{\{x\}/v}} is
translated to \sphinxcode{\sphinxupquote{/v\{x\}}}.

\end{enumerate}

\sphinxAtStartPar
In particular, the third rule lets one write \sphinxcode{\sphinxupquote{\{x\}/v}} even if \sphinxcode{\sphinxupquote{v}} uses the variable \sphinxcode{\sphinxupquote{x}}:
indeed the view is executed before the renaming.

\item {} 
\sphinxAtStartPar
An empty clear switch is now accepted in intro patterns before a
view application whenever the view is a variable.
One can now write \sphinxcode{\sphinxupquote{\{\}/v}} to mean \sphinxcode{\sphinxupquote{\{v\}/v}}.  Remark that \sphinxcode{\sphinxupquote{\{\}/x}} is very similar
to the idiom \sphinxcode{\sphinxupquote{\{\}e}} for the rewrite tactic (the equation \sphinxcode{\sphinxupquote{e}} is used for
rewriting and then discarded).

\end{itemize}

\sphinxAtStartPar
Standard Library
\begin{itemize}
\item {} 
\sphinxAtStartPar
There are now conversions between \sphinxcode{\sphinxupquote{string}} and \sphinxcode{\sphinxupquote{positive}}, \sphinxcode{\sphinxupquote{Z}},
\sphinxcode{\sphinxupquote{nat}}, and \sphinxcode{\sphinxupquote{N}} in binary, octal, and hex.

\end{itemize}

\sphinxAtStartPar
Display diffs between proof steps
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{coqtop}} and \sphinxcode{\sphinxupquote{coqide}} can now highlight the differences between proof steps
in color. This can be enabled from the command line or the
\sphinxcode{\sphinxupquote{Set Diffs "on"/"off"/"removed"}} command. Please see the documentation for
details.  Showing diffs in Proof General requires small changes to PG
(under discussion).

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added \sphinxcode{\sphinxupquote{++}} infix for \sphinxcode{\sphinxupquote{VectorDef.append}}.
Note that this might cause incompatibilities if you have, e.g., \sphinxcode{\sphinxupquote{list\_scope}}
and \sphinxcode{\sphinxupquote{vector\_scope}} both open with \sphinxcode{\sphinxupquote{vector\_scope}} on top, and expect \sphinxcode{\sphinxupquote{++}} to
refer to \sphinxcode{\sphinxupquote{app}}.
Solution: wrap \sphinxcode{\sphinxupquote{\_ ++ \_}} in \sphinxcode{\sphinxupquote{(\_ ++ \_)\%list}} (or whichever scope you want).

\end{itemize}


\paragraph{Changes in 8.8.0}
\label{\detokenize{changes:changes-in-8-8-0}}
\sphinxAtStartPar
Various bug fixes.


\paragraph{Changes in 8.8.1}
\label{\detokenize{changes:changes-in-8-8-1}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Some quality\sphinxhyphen{}of\sphinxhyphen{}life fixes.

\item {} 
\sphinxAtStartPar
Numerous improvements to the documentation.

\item {} 
\sphinxAtStartPar
Fix a critical bug related to primitive projections and {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.native_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{native\_compute}}}}}.

\item {} 
\sphinxAtStartPar
Ship several additional Coq libraries with the Windows installer.

\end{itemize}


\subsubsection{Version 8.8}
\label{\detokenize{changes:version-8-8}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id942}}
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
Kernel: fix a subject reduction failure due to allowing fixpoints
on non\sphinxhyphen{}recursive values, by Matthieu Sozeau.
Handling of evars in the VM (the kernel still does not accept evars)
by Pierre\sphinxhyphen{}Marie Pédrot.

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

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

\item {} 
\sphinxAtStartPar
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\sphinxhyphen{}Marie Pédrot.

\item {} 
\sphinxAtStartPar
Universes: many user\sphinxhyphen{}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\sphinxhyphen{}Marie
Pédrot and Matthieu Sozeau.

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

\item {} 
\sphinxAtStartPar
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\sphinxhyphen{}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\sphinxhyphen{}Claudel,
Laurence Rideau, Matthieu Sozeau, Paul Steckler, Enrico Tassi,
Laurent Théry, Nikita Zyuzin.

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

\end{itemize}

\sphinxAtStartPar
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.

\sphinxAtStartPar
Version 8.8 also comes with a bunch of smaller\sphinxhyphen{}scale changes and
improvements regarding the different components of the system.
Most important ones are documented in the next subsection file.

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

\sphinxAtStartPar
The official wiki and the bugtracker of 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.

\sphinxAtStartPar
The OPAM repository for 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/}.

\sphinxAtStartPar
The 44 contributors for this version are Yves Bertot, Joachim Breitner, Tej
Chajed, Arthur Charguéraud, Jacques\sphinxhyphen{}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\sphinxhyphen{}Marie Pédrot,
Clément Pit\sphinxhyphen{}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.

\sphinxAtStartPar
Version 8.8 is the third release of Coq developed on a time\sphinxhyphen{}based
development cycle. Its development spanned 6 months from the release of
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.

\sphinxAtStartPar
Many power users helped to improve the design of the new features via
the bug tracker, the pull request system, the Coq development mailing
list or the \sphinxhref{mailto:coq-club@inria.fr}{coq\sphinxhyphen{}club@inria.fr} mailing list. Special thanks to the users who
contributed patches and intensive brain\sphinxhyphen{}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.

\sphinxAtStartPar
The 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 Coq development team
\item[] 
\end{DUlineblock}


\paragraph{Details of changes in 8.8+beta1}
\label{\detokenize{changes:details-of-changes-in-8-8-beta1}}
\sphinxAtStartPar
Kernel
\begin{itemize}
\item {} 
\sphinxAtStartPar
Support for template polymorphism for definitions was removed. May trigger
more "universe inconsistency" errors in rare occasions.

\item {} 
\sphinxAtStartPar
Fixpoints are no longer allowed on non\sphinxhyphen{}recursive inductive types.

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
Recursive notations with the recursive pattern repeating on the
right (e.g. "( x ; .. ; y ; z )") now supported.

\item {} 
\sphinxAtStartPar
Notations with a specific level for the leftmost nonterminal,
when printing\sphinxhyphen{}only, are supported.

\item {} 
\sphinxAtStartPar
Notations can now refer to the syntactic category of patterns (as in
"fun 'pat =>" or "match p with pat => ... end"). Two variants are
available, depending on whether a single variable is considered as a
pattern or not.

\item {} 
\sphinxAtStartPar
Recursive notations now support ".." patterns with several
occurrences of the recursive term or binder, possibly mixing terms
and binders, possibly in reverse left\sphinxhyphen{}to\sphinxhyphen{}right order.

\item {} 
\sphinxAtStartPar
"Locate" now working also on notations of the form "x + y" (rather
than "\_ + \_").

\end{itemize}

\sphinxAtStartPar
Specification language
\begin{itemize}
\item {} 
\sphinxAtStartPar
When printing clauses of a "match", clauses with same right\sphinxhyphen{}hand
side are factorized and the last most factorized clause with no
variables, if it exists, is turned into a default clause.
Use "Unset Printing Allow Default Clause" do deactivate printing
of a default clause.
Use "Unset Printing Factorizable Match Patterns" to deactivate
factorization of clauses with same right\sphinxhyphen{}hand side.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
On Linux, "native\_compute" calls can be profiled using the "perf"
utility. The command "Set NativeCompute Profiling" enables
profiling, and "Set NativeCompute Profile Filename" customizes
the profile filename.

\item {} 
\sphinxAtStartPar
The tactic "omega" is now aware of the bodies of context variables
such as "x := 5 : Z" (see \#1362). This could be disabled via
Unset Omega UseLocalDefs.

\item {} 
\sphinxAtStartPar
The tactic "romega" is also aware now of the bodies of context variables.

\item {} 
\sphinxAtStartPar
The tactic "zify" resp. "omega with N" is now aware of N.pred.

\item {} 
\sphinxAtStartPar
Tactic "decide equality" now able to manage constructors which
contain proofs.

\item {} 
\sphinxAtStartPar
Added tactics reset ltac profile, show ltac profile (and variants)

\item {} 
\sphinxAtStartPar
Added tactics restart\_timer, finish\_timing, and time\_constr as an
experimental way of timing Ltac's evaluation phase

\item {} 
\sphinxAtStartPar
Added tactic optimize\_heap, analogous to the Vernacular Optimize
Heap, which performs a major garbage collection and heap compaction
in the OCaml run\sphinxhyphen{}time system.

\item {} 
\sphinxAtStartPar
The tactics "dtauto", "dintuition", "firstorder" now handle inductive types
with let bindings in the parameters.

\item {} 
\sphinxAtStartPar
The tactic \sphinxcode{\sphinxupquote{dtauto}} now handles some inductives such as
\sphinxcode{\sphinxupquote{@sigT A (fun \_ => B)}} as non\sphinxhyphen{}dependent conjunctions.

\item {} 
\sphinxAtStartPar
A bug fixed in \sphinxcode{\sphinxupquote{rewrite H in *}} and \sphinxcode{\sphinxupquote{rewrite H in * |\sphinxhyphen{}}} may cause a
few rare incompatibilities (it was unintendedly recursively
rewriting in the side conditions generated by H).

\item {} 
\sphinxAtStartPar
Added tactics "assert\_succeeds tac" and "assert\_fails tac" to ensure
properties of the execution of a tactic without keeping the effect
of the execution.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{vm\_compute}} now supports existential variables.

\item {} 
\sphinxAtStartPar
Calls to \sphinxcode{\sphinxupquote{shelve}} and \sphinxcode{\sphinxupquote{give\_up}} within calls to tactic \sphinxcode{\sphinxupquote{refine}} now working.

\item {} 
\sphinxAtStartPar
Deprecated tactic \sphinxcode{\sphinxupquote{appcontext}} was removed.

\end{itemize}

\sphinxAtStartPar
Focusing
\begin{itemize}
\item {} 
\sphinxAtStartPar
Focusing bracket \sphinxcode{\sphinxupquote{\{}} now supports single\sphinxhyphen{}numbered goal selector,
e.g. \sphinxcode{\sphinxupquote{2: \{}} will focus on the second subgoal. As usual, unfocus
with \sphinxcode{\sphinxupquote{\}}} once the subgoal is fully solved.
The \sphinxcode{\sphinxupquote{Focus}} and \sphinxcode{\sphinxupquote{Unfocus}} commands are now deprecated.

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
Proofs ending in "Qed exporting ident, .., ident" are not supported
anymore. Constants generated during \sphinxcode{\sphinxupquote{abstract}} are kept private to the
local environment.

\item {} 
\sphinxAtStartPar
The deprecated Coercion Local, Open Local Scope, Notation Local syntax
was removed. Use Local as a prefix instead.

\item {} 
\sphinxAtStartPar
For the Extraction Language command, "OCaml" is spelled correctly.
The older "Ocaml" is still accepted, but deprecated.

\item {} 
\sphinxAtStartPar
Using “Require” inside a section is deprecated.

\item {} 
\sphinxAtStartPar
An experimental command "Show Extraction" allows to extract the content
of the current ongoing proof (grant wish \#4129).

\item {} 
\sphinxAtStartPar
Coercion now accepts the type of its argument to be "Prop" or "Type".

\item {} 
\sphinxAtStartPar
The "Export" modifier can now be used when setting and unsetting options, and
will result in performing the same change when the module corresponding the
command is imported.

\item {} 
\sphinxAtStartPar
The \sphinxcode{\sphinxupquote{Axiom}} command does not automatically declare axioms as instances when
their type is a class. Previous behavior can be restored using \sphinxcode{\sphinxupquote{Set
Typeclasses Axioms Are Instances}}.

\end{itemize}

\sphinxAtStartPar
Universes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Qualified naming of global universes now works like other namespaced
objects (e.g. constants), with a separate namespace, inside and across
module and library boundaries. Global universe names introduced in an
inductive / constant / Let declaration get qualified with the name of
the declaration.

\item {} 
\sphinxAtStartPar
Universe cumulativity for inductive types is now specified as a
variance for each polymorphic universe. See the reference manual for
more information.

\item {} 
\sphinxAtStartPar
Inference of universe constraints with cumulative inductive types
produces more general constraints. Unsetting new option Cumulativity
Weak Constraints produces even more general constraints (but may
produce too many universes to be practical).

\item {} 
\sphinxAtStartPar
Fix \#5726: Notations that start with \sphinxcode{\sphinxupquote{Type}} now support universe instances
with \sphinxcode{\sphinxupquote{@\{u\}}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{with Definition}} now understands universe declarations
(like \sphinxcode{\sphinxupquote{@\{u| Set < u\}}}).

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Coq can now be run with the option \sphinxhyphen{}mangle\sphinxhyphen{}names to change the auto\sphinxhyphen{}generated
name scheme. This is intended to function as a linter for developments that
want to be robust to changes in auto\sphinxhyphen{}generated names. This feature is experimental,
and may change or disappear without warning.

\item {} 
\sphinxAtStartPar
GeoProof support was removed.

\end{itemize}

\sphinxAtStartPar
Checker
\begin{itemize}
\item {} 
\sphinxAtStartPar
The checker now accepts filenames in addition to logical paths.

\end{itemize}

\sphinxAtStartPar
CoqIDE
\begin{itemize}
\item {} 
\sphinxAtStartPar
Find and Replace All report the number of occurrences found; Find indicates
when it wraps.

\end{itemize}

\sphinxAtStartPar
coqdep
\begin{itemize}
\item {} 
\sphinxAtStartPar
Learned to read \sphinxhyphen{}I, \sphinxhyphen{}Q, \sphinxhyphen{}R and filenames from \_CoqProject files.
This is used by coq\_makefile when generating dependencies for .v
files (but not other files).

\end{itemize}

\sphinxAtStartPar
Documentation
\begin{itemize}
\item {} 
\sphinxAtStartPar
The Coq FAQ, formerly located at \sphinxurl{https://coq.inria.fr/faq}, has been
moved to the GitHub wiki section of this repository; the main entry
page is \sphinxurl{https://github.com/coq/coq/wiki/The-Coq-FAQ}.

\item {} 
\sphinxAtStartPar
Documentation: a large community effort resulted in the migration
of the reference manual to the Sphinx documentation tool. The result
is partially integrated in this version.

\end{itemize}

\sphinxAtStartPar
Standard Library
\begin{itemize}
\item {} 
\sphinxAtStartPar
New libraries Coq.Init.Decimal, Coq.Numbers.DecimalFacts,
Coq.Numbers.DecimalNat, Coq.Numbers.DecimalPos,
Coq.Numbers.DecimalN, Coq.Numbers.DecimalZ,
Coq.Numbers.DecimalString providing a type of decimal numbers, some
facts about them, and conversions between decimal numbers and nat,
positive, N, Z, and string.

\item {} 
\sphinxAtStartPar
Added {[}Coq.Strings.String.concat{]} to concatenate a list of strings
inserting a separator between each item

\item {} 
\sphinxAtStartPar
Notation \sphinxcode{\sphinxupquote{'}} for Zpos in QArith was removed.

\item {} 
\sphinxAtStartPar
Some deprecated aliases are now emitting warnings when used.

\end{itemize}

\sphinxAtStartPar
Compatibility support
\begin{itemize}
\item {} 
\sphinxAtStartPar
Support for compatibility with versions before 8.6 was dropped.

\end{itemize}

\sphinxAtStartPar
Options
\begin{itemize}
\item {} 
\sphinxAtStartPar
The following deprecated options have been removed:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Refolding Reduction}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Standard Proposition Elimination}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Dependent Propositions Elimination}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Discriminate Introduction}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Shrink Abstract}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Tactic Pattern Unification}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Intuition Iff Unfolding}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Injection L2R Pattern Order}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Record Elimination Schemes}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Match Strict}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Tactic Compat Context}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Typeclasses Legacy Resolution}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Typeclasses Module Eta}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Typeclass Resolution After Apply}}

\end{itemize}

\end{itemize}


\paragraph{Details of changes in 8.8.0}
\label{\detokenize{changes:details-of-changes-in-8-8-0}}
\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Asynchronous proof delegation policy was fixed. Since version 8.7
Coq was ignoring previous runs and the \sphinxcode{\sphinxupquote{\sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}delegation\sphinxhyphen{}threshold}}
option did not have the expected behavior.

\end{itemize}

\sphinxAtStartPar
Tactic language
\begin{itemize}
\item {} 
\sphinxAtStartPar
The undocumented "nameless" forms \sphinxcode{\sphinxupquote{fix N}}, \sphinxcode{\sphinxupquote{cofix}} have been
deprecated; please use \sphinxcode{\sphinxupquote{fix ident N /cofix ident}} to explicitly
name the (co)fixpoint hypothesis to be introduced.

\end{itemize}

\sphinxAtStartPar
Documentation
\begin{itemize}
\item {} 
\sphinxAtStartPar
The reference manual is now fully ported to Sphinx.

\end{itemize}

\sphinxAtStartPar
Other small deprecations and bug fixes.


\paragraph{Details of changes in 8.8.1}
\label{\detokenize{changes:details-of-changes-in-8-8-1}}
\sphinxAtStartPar
Kernel
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix a critical bug with cofixpoints and \sphinxcode{\sphinxupquote{vm\_compute}}/\sphinxcode{\sphinxupquote{native\_compute}} (\#7333).

\item {} 
\sphinxAtStartPar
Fix a critical bug with modules and algebraic universes (\#7695)

\item {} 
\sphinxAtStartPar
Fix a critical bug with inlining of polymorphic constants (\#7615).

\item {} 
\sphinxAtStartPar
Fix a critical bug with universe polymorphism and \sphinxcode{\sphinxupquote{vm\_compute}} (\#7723). Was
present since 8.5.

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fixed unexpected collision between only\sphinxhyphen{}parsing and only\sphinxhyphen{}printing
notations (issue \#7462).

\end{itemize}

\sphinxAtStartPar
Windows installer
\begin{itemize}
\item {} 
\sphinxAtStartPar
The Windows installer now includes external packages Ltac2 and Equations
(it included the Bignums package since 8.8+beta1).

\end{itemize}

\sphinxAtStartPar
Many other bug fixes, documentation improvements (including fixes of
regressions due to the Sphinx migration), and user message improvements
(for details, see the 8.8.1 milestone at
\sphinxurl{https://github.com/coq/coq/milestone/13?closed=1}).


\paragraph{Details of changes in 8.8.2}
\label{\detokenize{changes:details-of-changes-in-8-8-2}}
\sphinxAtStartPar
Documentation
\begin{itemize}
\item {} 
\sphinxAtStartPar
A PDF version of the reference manual is available once again.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
The coq\sphinxhyphen{}makefile targets \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed}}, \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}},
and \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}single\sphinxhyphen{}time\sphinxhyphen{}diff}} now correctly label the "before" and
"after" columns, rather than swapping them.

\end{itemize}

\sphinxAtStartPar
Kernel
\begin{itemize}
\item {} 
\sphinxAtStartPar
The kernel does not tolerate capture of global universes by
polymorphic universe binders, fixing a soundness break (triggered
only through custom plugins)

\end{itemize}

\sphinxAtStartPar
Windows installer
\begin{itemize}
\item {} 
\sphinxAtStartPar
The Windows installer now includes many more external packages that can be
individually selected for installation.

\end{itemize}

\sphinxAtStartPar
Many other bug fixes and lots of documentation improvements (for details,
see the 8.8.2 milestone at \sphinxurl{https://github.com/coq/coq/milestone/15?closed=1}).


\subsubsection{Version 8.7}
\label{\detokenize{changes:version-8-7}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id943}}
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
New tactics: variants of tactics supporting existential variables {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eassert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eassert}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eenough}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eenough}}}}}, etc... by Hugo Herbelin. Tactics \sphinxcode{\sphinxupquote{extensionality in H}} and
{\hyperref[\detokenize{proofs/writing-proofs/reasoning-inductives:coq:tacv.inversion_sigma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion\_sigma}}}}} by Jason Gross, \sphinxcode{\sphinxupquote{specialize with ...}} accepting partial bindings
by Pierre Courtieu.

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

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

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

\end{itemize}

\sphinxAtStartPar
Coq 8.7 involved a large amount of work on cleaning and speeding up the code
base, notably the work of Pierre\sphinxhyphen{}Marie Pédrot on making the tactic\sphinxhyphen{}level system
insensitive to existential variable expansion, providing a safer API to plugin
writers and making the code more robust. The \sphinxcode{\sphinxupquote{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.

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

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

\sphinxAtStartPar
Thomas Sibut\sphinxhyphen{}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/}.

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

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

\sphinxAtStartPar
Standard library additions and improvements by Jason Gross, Pierre Letouzey and
others, documented in the next subsection file.

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

\sphinxAtStartPar
The OPAM repository for 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/}.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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\sphinxhyphen{}Dorel, Olivier Marty, Guillaume Melquiond, Sam Pablo Kuper,
Benjamin Pierce, Pierre\sphinxhyphen{}Marie Pédrot, Lars Rasmusson, Lionel Rieg, Valentin
Robert, Yann Régis\sphinxhyphen{}Gianas, Thomas Sibut\sphinxhyphen{}Pinote, Michael Soegtrop, Matthieu
Sozeau, Arnaud Spiwack, Paul Steckler, George Stelle, Pierre\sphinxhyphen{}Yves Strub, Enrico
Tassi, Hendrik Tews, Amin Timany, Laurent Théry, Vadim Zaliva and Théo
Zimmermann.

\sphinxAtStartPar
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.

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

\sphinxAtStartPar
Version 8.7 is the second release of Coq developed on a time\sphinxhyphen{}based development
cycle. Its development spanned 9 months from the release of Coq 8.6 and was
based on a public road\sphinxhyphen{}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 Coq 8.6
while maintaining compatibility.

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

\sphinxAtStartPar
The 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 Coq development team
\item[] 
\end{DUlineblock}


\paragraph{Potential compatibility issues}
\label{\detokenize{changes:potential-compatibility-issues}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Extra superfluous names in introduction patterns may now raise an
error rather than a warning when the superfluous name is already in
use. The easy fix is to remove the superfluous name.

\end{itemize}


\paragraph{Details of changes in 8.7+beta1}
\label{\detokenize{changes:details-of-changes-in-8-7-beta1}}
\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New tactic "extensionality in H" which applies (possibly dependent)
functional extensionality in H supposed to be a quantified equality
until giving a bare equality.

\item {} 
\sphinxAtStartPar
New tactic \sphinxcode{\sphinxupquote{inversion\_sigma}} which turns equalities of dependent
pairs (e.g., \sphinxcode{\sphinxupquote{existT P x p = existT P y q}}, frequently left over by
\sphinxcode{\sphinxupquote{inversion}} on a dependent type family) into pairs of equalities
(e.g., a hypothesis \sphinxcode{\sphinxupquote{H : x = y}} and a hypothesis of type \sphinxcode{\sphinxupquote{rew H in p = q}});
these hypotheses can subsequently be simplified using
\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{induction H as {[}H1 H2{]} using eq\_sigT\_rect}}.  The tactic also
works for \sphinxcode{\sphinxupquote{sig}}, \sphinxcode{\sphinxupquote{sigT2}}, and \sphinxcode{\sphinxupquote{sig2}}, and there are similar
\sphinxcode{\sphinxupquote{eq\_sig*\_rect}} induction lemmas.

\item {} 
\sphinxAtStartPar
Tactic "specialize with ..." now accepts any partial bindings.
Missing bindings are either solved by unification or left quantified
in the hypothesis.

\item {} 
\sphinxAtStartPar
New representation of terms that statically ensure stability by
evar\sphinxhyphen{}expansion. This has several consequences.
\begin{itemize}
\item {} 
\sphinxAtStartPar
In terms of performance, this adds a cost to every term destructuration,
but at the same time most eager evar normalizations were removed, which
couterbalances this drawback and even sometimes outperforms the old
implementation. For instance, many operations that would require O(n)
normalization of the term are now O(1) in tactics. YMMV.

\item {} 
\sphinxAtStartPar
This triggers small changes in unification, which was not evar\sphinxhyphen{}insensitive.
Most notably, the new implementation recognizes Miller patterns that were
missed before because of a missing normalization step. Hopefully this should
be fairly uncommon.

\end{itemize}

\item {} 
\sphinxAtStartPar
Tactic "auto with real" can now discharge comparisons of literals.

\item {} 
\sphinxAtStartPar
The types of variables in patterns of "match" are now
beta\sphinxhyphen{}iota\sphinxhyphen{}reduced after type checking. This has an impact on the
type of the variables that the tactic "refine" introduces in the
context, producing types that should be closer to the expectations.

\item {} 
\sphinxAtStartPar
In "Tactic Notation" or "TACTIC EXTEND", entry "constr\_with\_bindings"
now uses type classes and rejects terms with unresolved holes, like
entry "constr" does. To get the former behavior use
"open\_constr\_with\_bindings" (possible source of incompatibility).

\item {} 
\sphinxAtStartPar
New e\sphinxhyphen{}variants eassert, eenough, epose proof, eset, eremember, epose
which behave like the corresponding variants with no "e" but turn
unresolved implicit arguments into existential variables, on the
shelf, rather than failing.

\item {} 
\sphinxAtStartPar
Tactic injection has become more powerful (closes bug \#4890) and its
documentation has been updated.

\item {} 
\sphinxAtStartPar
New variants of the \sphinxcode{\sphinxupquote{first}} and \sphinxcode{\sphinxupquote{solve}} tacticals that do not rely
on parsing rules, meant to define tactic notations.

\item {} 
\sphinxAtStartPar
Added support for side effects hooks in \sphinxcode{\sphinxupquote{cbv}}, \sphinxcode{\sphinxupquote{cbn}} and \sphinxcode{\sphinxupquote{simpl}}.
The side effects are provided via a plugin:
\sphinxurl{https://github.com/herbelin/reduction-effects/}

\item {} 
\sphinxAtStartPar
It is now possible to take hint database names as parameters in a
Ltac definition or a Tactic Notation.

\item {} 
\sphinxAtStartPar
New option \sphinxcode{\sphinxupquote{Set Ltac Batch Debug}} on top of \sphinxcode{\sphinxupquote{Set Ltac Debug}} for
non\sphinxhyphen{}interactive Ltac debug output.

\end{itemize}

\sphinxAtStartPar
Gallina
\begin{itemize}
\item {} 
\sphinxAtStartPar
Now supporting all kinds of binders, including 'pat, in syntax of record fields.

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
Goals context can be printed in a more compact way when \sphinxcode{\sphinxupquote{Set
Printing Compact Contexts}} is activated.

\item {} 
\sphinxAtStartPar
Unfocused goals can be printed with the \sphinxcode{\sphinxupquote{Set Printing Unfocused}}
option.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Print}} now shows the types of let\sphinxhyphen{}bindings.

\item {} 
\sphinxAtStartPar
The compatibility options for printing primitive projections
(\sphinxcode{\sphinxupquote{Set Printing Primitive Projection Parameters}} and
\sphinxcode{\sphinxupquote{Set Printing Primitive Projection Compatibility}}) are now off by default.

\item {} 
\sphinxAtStartPar
Possibility to unset the printing of notations in a more fine grained
fashion than \sphinxcode{\sphinxupquote{Unset Printing Notations}} is provided without any
user\sphinxhyphen{}syntax. The goal is that someone creates a plugin to experiment
such a user\sphinxhyphen{}syntax, to be later integrated in Coq when stabilized.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{About}} now tells if a reference is a coercion.

\item {} 
\sphinxAtStartPar
The deprecated \sphinxcode{\sphinxupquote{Save}} vernacular and its form \sphinxcode{\sphinxupquote{Save Theorem id}} to
close proofs have been removed from the syntax. Please use \sphinxcode{\sphinxupquote{Qed}}.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Search}} now sorts results by relevance (the relevance metric is a
weighted sum of number of distinct symbols and size of the term).

\end{itemize}

\sphinxAtStartPar
Standard Library
\begin{itemize}
\item {} 
\sphinxAtStartPar
New file PropExtensionality.v to explicitly work in the axiomatic
context of propositional extensionality.

\item {} 
\sphinxAtStartPar
New file SetoidChoice.v axiomatically providing choice over setoids,
and, consequently, choice of representatives in equivalence classes.
Various proof\sphinxhyphen{}theoretic characterizations of choice over setoids in
file ChoiceFacts.v.

\item {} 
\sphinxAtStartPar
New lemmas about iff and about orders on positive and Z.

\item {} 
\sphinxAtStartPar
New lemmas on powerRZ.

\item {} 
\sphinxAtStartPar
Strengthened statement of JMeq\_eq\_dep (closes bug \#4912).

\item {} 
\sphinxAtStartPar
The BigN, BigZ, BigZ libraries are no longer part of the Coq standard
library, they are now provided by a separate repository
\sphinxurl{https://github.com/coq/bignums}
The split has been done just after the Int31 library.

\item {} 
\sphinxAtStartPar
IZR (Reals) has been changed to produce a compact representation of
integers. As a consequence, IZR is no longer convertible to INR and
lemmas such as INR\_IZR\_INZ should be used instead.

\item {} 
\sphinxAtStartPar
Real constants are now represented using IZR rather than R0 and R1;
this might cause rewriting rules to fail to apply to constants.

\item {} 
\sphinxAtStartPar
Added new notation \{x \& P\} for sigT (without a type for x)

\end{itemize}

\sphinxAtStartPar
Plugins
\begin{itemize}
\item {} 
\sphinxAtStartPar
The Ssreflect plugin is now distributed with Coq. Its documentation has
been integrated as a chapter of the reference manual. This chapter is
work in progress so feedback is welcome.

\item {} 
\sphinxAtStartPar
The mathematical proof language (also known as declarative mode) was removed.

\item {} 
\sphinxAtStartPar
A new command Extraction TestCompile has been introduced, not meant
for the general user but instead for Coq's test\sphinxhyphen{}suite.

\item {} 
\sphinxAtStartPar
The extraction plugin is no longer loaded by default. It must be
explicitly loaded with {[}Require Extraction{]}, which is backwards
compatible.

\item {} 
\sphinxAtStartPar
The functional induction plugin (which provides the {[}Function{]}
vernacular) is no longer loaded by default. It must be explicitly
loaded with {[}Require FunInd{]}, which is backwards compatible.

\end{itemize}

\sphinxAtStartPar
Dependencies
\begin{itemize}
\item {} 
\sphinxAtStartPar
Support for camlp4 has been removed.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
coq\_makefile was completely redesigned to improve its maintainability and
the extensibility of generated Makefiles, and to make \_CoqProject files
more palatable to IDEs.  Overview:
\begin{itemize}
\item {} 
\sphinxAtStartPar
\_CoqProject files contain only Coq specific data (i.e. the list of
files, \sphinxhyphen{}R options, ...)

\item {} 
\sphinxAtStartPar
coq\_makefile translates \_CoqProject to Makefile.conf and copies in the
desired location a standard Makefile (that reads Makefile.conf)

\item {} 
\sphinxAtStartPar
Makefile extensions can be implemented in a Makefile.local file (read
by the main Makefile) by installing a hook in the extension points
provided by the standard Makefile

\end{itemize}

\sphinxAtStartPar
The current version contains code for retro compatibility that prints
warnings when a deprecated feature is used.  Please upgrade your \_CoqProject
accordingly.
\begin{itemize}
\item {} 
\sphinxAtStartPar
Additionally, coq\_makefile\sphinxhyphen{}made Makefiles now support experimental timing
targets \sphinxcode{\sphinxupquote{pretty\sphinxhyphen{}timed}}, \sphinxcode{\sphinxupquote{pretty\sphinxhyphen{}timed\sphinxhyphen{}before}}, \sphinxcode{\sphinxupquote{pretty\sphinxhyphen{}timed\sphinxhyphen{}after}},
\sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}timed\sphinxhyphen{}diff}}, \sphinxcode{\sphinxupquote{print\sphinxhyphen{}pretty\sphinxhyphen{}single\sphinxhyphen{}time\sphinxhyphen{}diff}},
\sphinxcode{\sphinxupquote{all.timing.diff}}, and the variable \sphinxcode{\sphinxupquote{TIMING=1}} (or \sphinxcode{\sphinxupquote{TIMING=before}} or
\sphinxcode{\sphinxupquote{TIMING=after}}); see the documentation for more details.

\end{itemize}

\end{itemize}

\sphinxAtStartPar
Build Infrastructure
\begin{itemize}
\item {} 
\sphinxAtStartPar
Note that 'make world' does not build the bytecode binaries anymore.
For that, you can use 'make byte' (and 'make install\sphinxhyphen{}byte' afterwards).
Warning: native and byte compilations should \sphinxstyleemphasis{not} be mixed in the same
instance of 'make \sphinxhyphen{}j', otherwise both ocamlc and ocamlopt might race for
access to the same .cmi files. In short, use "make \sphinxhyphen{}j \&\& make \sphinxhyphen{}j byte"
instead of "make \sphinxhyphen{}j world byte".

\end{itemize}

\sphinxAtStartPar
Universes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Cumulative inductive types. see prefixes "Cumulative", "NonCumulative"
for inductive definitions and the option "Set Polymorphic Inductive Cumulativity"
in the reference manual.

\item {} 
\sphinxAtStartPar
New syntax \sphinxcode{\sphinxupquote{foo@\{\_\}}} to instantiate a polymorphic definition with
anonymous universes (can also be used with \sphinxcode{\sphinxupquote{Type}}).

\end{itemize}

\sphinxAtStartPar
XML Protocol and internal changes

\sphinxAtStartPar
See dev/doc/changes.txt

\sphinxAtStartPar
Many bugfixes including \#1859, \#2884, \#3613, \#3943, \#3994,
\#4250, \#4709, \#4720, \#4824, \#4844, \#4911, \#5026, \#5233,
\#5275, \#5315, \#5336, \#5360, \#5390, \#5414, \#5417, \#5420,
\#5439, \#5449, \#5475, \#5476, \#5482, \#5501, \#5507, \#5520,
\#5523, \#5524, \#5553, \#5577, \#5578, \#5589, \#5597, \#5598,
\#5607, \#5618, \#5619, \#5620, \#5641, \#5648, \#5651, \#5671.

\sphinxAtStartPar
Many bugfixes on OS X and Windows (now the test\sphinxhyphen{}suite passes on these
platforms too).

\sphinxAtStartPar
Many optimizations.

\sphinxAtStartPar
Many documentation improvements.


\paragraph{Details of changes in 8.7+beta2}
\label{\detokenize{changes:details-of-changes-in-8-7-beta2}}
\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
In CoqIDE, the "Compile Buffer" command takes account of flags in
\_CoqProject or other project file.

\end{itemize}

\sphinxAtStartPar
Improvements around some error messages.

\sphinxAtStartPar
Many bug fixes including two important ones:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Bug \#5730: CoqIDE becomes unresponsive on file open.

\item {} 
\sphinxAtStartPar
coq\_makefile: make sure compile flags for Coq and coq\_makefile are in sync
(in particular, make sure the \sphinxcode{\sphinxupquote{\sphinxhyphen{}safe\sphinxhyphen{}string}} option is used to compile plugins).

\end{itemize}


\paragraph{Details of changes in 8.7.0}
\label{\detokenize{changes:details-of-changes-in-8-7-0}}
\sphinxAtStartPar
OCaml
\begin{itemize}
\item {} 
\sphinxAtStartPar
Users can pass specific flags to the OCaml optimizing compiler by
\sphinxhyphen{}using the flambda\sphinxhyphen{}opts configure\sphinxhyphen{}time option.

\sphinxAtStartPar
Beware that compiling Coq with a flambda\sphinxhyphen{}enabled compiler is
experimental and may require large amounts of RAM and CPU, see
INSTALL for more details.

\end{itemize}


\paragraph{Details of changes in 8.7.1}
\label{\detokenize{changes:details-of-changes-in-8-7-1}}
\sphinxAtStartPar
Compatibility with OCaml 4.06.0.

\sphinxAtStartPar
Many bug fixes, documentation improvements, and user message improvements (for
details see the 8.7.1 milestone at \sphinxurl{https://github.com/coq/coq/milestone/10?closed=1}).


\paragraph{Details of changes in 8.7.2}
\label{\detokenize{changes:details-of-changes-in-8-7-2}}
\sphinxAtStartPar
Fixed a critical bug in the VM handling of universes (\#6677). This bug
affected all releases since 8.5.

\sphinxAtStartPar
Improved support for building with OCaml 4.06.0 and external num package.

\sphinxAtStartPar
Many other bug fixes, documentation improvements, and user
message improvements (for details, see the 8.7.2 milestone at
\sphinxurl{https://github.com/coq/coq/milestone/11?closed=1}).


\subsubsection{Version 8.6}
\label{\detokenize{changes:version-8-6}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id944}}
\sphinxAtStartPar
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\sphinxhyphen{}based) development, about 450 bugs were resolved and
over 100 contributions integrated. The main user visible changes are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
A new, faster state\sphinxhyphen{}of\sphinxhyphen{}the\sphinxhyphen{}art universe constraint checker, by
Jacques\sphinxhyphen{}Henri Jourdan.

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

\item {} 
\sphinxAtStartPar
More access to the proof engine features from Ltac: goal management
primitives, range selectors and a {\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}} engine handling
multiple goals and multiple successes, by Cyprien Mangin, Matthieu
Sozeau and Arnaud Spiwack.

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

\item {} 
\sphinxAtStartPar
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\sphinxhyphen{}Marie Pédrot and others.

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

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

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

\end{itemize}

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

\sphinxAtStartPar
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).

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

\sphinxAtStartPar
Pierre\sphinxhyphen{}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.

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

\sphinxAtStartPar
Name handling for universes has been improved by Pierre\sphinxhyphen{}Marie Pédrot and
Matthieu Sozeau. The minimization algorithm has been improved by
Matthieu Sozeau.

\sphinxAtStartPar
The unifier has been improved by Hugo Herbelin and Matthieu Sozeau,
fixing some incompatibilities introduced in 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.

\sphinxAtStartPar
The typeclass resolution engine and associated proof search tactic have
been reimplemented on top of the proof\sphinxhyphen{}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.

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

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

\sphinxAtStartPar
Emilio Jesús Gallego Arias contributed many cleanups and refactorings of
the pretty\sphinxhyphen{}printing and user interface communication components.

\sphinxAtStartPar
Frédéric Besson maintained the micromega tactic.

\sphinxAtStartPar
The OPAM repository for 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/}.

\sphinxAtStartPar
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. Coq now comes with a META
file usable with ocamlfind, contributed by Emilio Jesús Gallego Arias,
Gregory Malecha, and Matthieu Sozeau.

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

\sphinxAtStartPar
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\sphinxhyphen{}Henri Jourdan, Matej Košík, Xavier Leroy,
Pierre Letouzey, Gregory Malecha, Cyprien Mangin, Erik Martin\sphinxhyphen{}Dorel,
Guillaume Melquiond, Clément Pit–Claudel, Pierre\sphinxhyphen{}Marie Pédrot, Daniel de
Rauglaudre, Lionel Rieg, Gabriel Scherer, Thomas Sibut\sphinxhyphen{}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.

\sphinxAtStartPar
Many power users helped to improve the design of the new features via
the bug tracker, the pull request system, the Coq development mailing
list or the Coq\sphinxhyphen{}Club mailing list. Special thanks to the users who
contributed patches and intensive brain\sphinxhyphen{}storming and code reviews,
starting with Cyril Cohen, Jason Gross, Robbert Krebbers, Jonathan
Leivent, Xavier Leroy, Gregory Malecha, Clément Pit–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.

\sphinxAtStartPar
Version 8.6 is the first release of Coq developed on a time\sphinxhyphen{}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 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 Coq 8.5.

\sphinxAtStartPar
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}.

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

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


\paragraph{Potential sources of incompatibilities}
\label{\detokenize{changes:potential-sources-of-incompatibilities}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Symptom: An obligation generated by Program or an abstracted subproof
has different arguments.

\sphinxAtStartPar
Cause: Set Shrink Abstract and Set Shrink Obligations are on by default
and the subproof does not use the argument.

\sphinxAtStartPar
Remedy:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Adapt the script.

\item {} 
\sphinxAtStartPar
Write an explicit lemma to prove the obligation/subproof and use it
instead (compatible with 8.4).

\item {} 
\sphinxAtStartPar
Unset the option for the program/proof the obligation/subproof originates
from.

\end{itemize}

\item {} 
\sphinxAtStartPar
Symptom: In a goal, order of hypotheses, or absence of an equality of
the form "x = t" or "t = x", or no unfolding of a local definition.

\sphinxAtStartPar
Cause: This might be connected to a number of fixes in the tactic
"subst". The former behavior can be reactivated by issuing "Unset
Regular Subst Tactic".

\end{itemize}


\paragraph{Details of changes in 8.6beta1}
\label{\detokenize{changes:details-of-changes-in-8-6beta1}}
\sphinxAtStartPar
Kernel
\begin{itemize}
\item {} 
\sphinxAtStartPar
A new, faster state\sphinxhyphen{}of\sphinxhyphen{}the\sphinxhyphen{}art universe constraint checker.

\end{itemize}

\sphinxAtStartPar
Specification language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Giving implicit arguments explicitly to a constant with multiple
choices of implicit arguments does not break any more insertion of
further maximal implicit arguments.

\item {} 
\sphinxAtStartPar
Ability to put any pattern in binders, prefixed by quote, e.g.
"fun '(a,b) => ...", "λ '(a,(b,c)), ...", "Definition foo '(x,y) := ...".
It expands into a "let 'pattern := ..."

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Flag "Bracketing Last Introduction Pattern" is now on by default.

\item {} 
\sphinxAtStartPar
Flag "Regular Subst Tactic" is now on by default: it respects the
initial order of hypothesis, it contracts cycles, it unfolds no
local definitions (common source of incompatibilities, fixable by
"Unset Regular Subst Tactic").

\item {} 
\sphinxAtStartPar
New flag "Refolding Reduction", now disabled by default, which turns
on refolding of constants/fixpoints (as in cbn) during the reductions
done during type inference and tactic retyping. Can be extremely
expensive. When set off, this recovers the 8.4 behaviour of unification
and type inference. Potential source of incompatibility with 8.5 developments
(the option is set on in Compat/Coq85.v).

\item {} 
\sphinxAtStartPar
New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
tactical w.r.t. variables appearing in the body of the proof.
On by default and deprecated. Minor source of incompatibility
for code relying on the precise arguments of abstracted proofs.

\item {} 
\sphinxAtStartPar
Serious bugs are fixed in tactic "double induction" (source of
incompatibilities as soon as the inductive types have dependencies in
the type of their constructors; "double induction" remains however
deprecated).

\item {} 
\sphinxAtStartPar
In introduction patterns of the form (pat1,...,patn), n should match
the exact number of hypotheses introduced (except for local definitions
for which pattern can be omitted, as in regular pattern\sphinxhyphen{}matching).

\item {} 
\sphinxAtStartPar
Tactic scopes in Ltac like constr: and ltac: now require parentheses around
their argument.

\item {} 
\sphinxAtStartPar
Every generic argument type declares a tactic scope of the form "name:(...)"
where name is the name of the argument. This generalizes the constr: and ltac:
instances.

\item {} 
\sphinxAtStartPar
When in strict mode (i.e. in a Ltac definition), if the "intro" tactic is
given a free identifier, it is not bound in subsequent tactics anymore.
In order to introduce a binding, use e.g. the "fresh" primitive instead
(potential source of incompatibilities).

\item {} 
\sphinxAtStartPar
New tactics is\_ind, is\_const, is\_proj, is\_constructor for use in Ltac.

\item {} 
\sphinxAtStartPar
New goal selectors.  Sets of goals can be selected by listing integers
ranges. Example: "1,4\sphinxhyphen{}7,24: tac" focuses "tac" on goals 1,4,5,6,7,24.

\item {} 
\sphinxAtStartPar
For uniformity with "destruct"/"induction" and for a more natural
behavior, "injection" can now work in place by activating option
"Structural Injection". In this case, hypotheses are also put in the
context in the natural left\sphinxhyphen{}to\sphinxhyphen{}right order and the hypothesis on
which injection applies is cleared.

\item {} 
\sphinxAtStartPar
Tactic "contradiction" (hence "easy") now also solve goals with
hypotheses of the form "\textasciitilde{}True" or "t<>t" (possible source of
incompatibilities because of more successes in automation, but
generally a more intuitive strategy).

\item {} 
\sphinxAtStartPar
Option "Injection On Proofs" was renamed "Keep Proof Equalities". When
enabled, injection and inversion do not drop equalities between objects
in Prop. Still disabled by default.

\item {} 
\sphinxAtStartPar
New tactics "notypeclasses refine" and "simple notypeclasses refine" that
disallow typeclass resolution when typechecking their argument, for use
in typeclass hints.

\item {} 
\sphinxAtStartPar
Integration of LtacProf, a profiler for Ltac.

\item {} 
\sphinxAtStartPar
Reduction tactics now accept more fine\sphinxhyphen{}grained flags: iota is now a shorthand
for the new flags match, fix and cofix.

\item {} 
\sphinxAtStartPar
The ssreflect subterm selection algorithm is now accessible to tactic writers
through the ssrmatching plugin.

\item {} 
\sphinxAtStartPar
When used as an argument of an ltac function, "auto" without "with"
nor "using" clause now correctly uses only the core hint database by
default.

\end{itemize}

\sphinxAtStartPar
Hints
\begin{itemize}
\item {} 
\sphinxAtStartPar
Revised the syntax of {[}Hint Cut{]} to follow standard notation for regexps.

\item {} 
\sphinxAtStartPar
Hint Mode now accepts "!" which means that the mode matches only if the
argument's head is not an evar (it goes under applications, casts, and
scrutinees of matches and projections).

\item {} 
\sphinxAtStartPar
Hints can now take an optional user\sphinxhyphen{}given pattern, used only by
{[}typeclasses eauto{]} with the {[}Filtered Unification{]} option on.

\end{itemize}

\sphinxAtStartPar
Typeclasses
\begin{itemize}
\item {} 
\sphinxAtStartPar
Many new options and new engine based on the proof monad. The
{[}typeclasses eauto{]} tactic is now a multi\sphinxhyphen{}goal, multi\sphinxhyphen{}success tactic.
See reference manual for more information. It is planned to
replace auto and eauto in the following version. The 8.5 resolution
engine is still available to help solve compatibility issues.

\end{itemize}

\sphinxAtStartPar
Program
\begin{itemize}
\item {} 
\sphinxAtStartPar
The "Shrink Obligations" flag now applies to all obligations, not only
those solved by the automatic tactic.

\item {} 
\sphinxAtStartPar
"Shrink Obligations" is on by default and deprecated. Minor source of
incompatibility for code relying on the precise arguments of
obligations.

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Bind Scope" can once again bind "Funclass" and "Sortclass".

\end{itemize}

\sphinxAtStartPar
General infrastructure
\begin{itemize}
\item {} 
\sphinxAtStartPar
New configurable warning system which can be controlled with the vernacular
command "Set Warnings", or, under coqc/coqtop, with the flag "\sphinxhyphen{}w". In
particular, the default is now that warnings are printed by coqc.

\item {} 
\sphinxAtStartPar
In asynchronous mode, Coq is now capable of recovering from errors and
continue processing the document.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
coqc accepts a \sphinxhyphen{}o option to specify the output file name

\item {} 
\sphinxAtStartPar
coqtop accepts \sphinxhyphen{}\sphinxhyphen{}print\sphinxhyphen{}version to print Coq and OCaml versions in
easy to parse format

\item {} 
\sphinxAtStartPar
Setting {[}Printing Dependent Evars Line{]} can be unset to disable the
computation associated with printing the "dependent evars: " line in
\sphinxhyphen{}emacs mode

\item {} 
\sphinxAtStartPar
Removed the \sphinxhyphen{}verbose\sphinxhyphen{}compat\sphinxhyphen{}notations flag and the corresponding Set
Verbose Compat vernacular, since these warnings can now be silenced or
turned into errors using "\sphinxhyphen{}w".

\end{itemize}

\sphinxAtStartPar
XML protocol
\begin{itemize}
\item {} 
\sphinxAtStartPar
message format has changed, see dev/doc/changes.txt for more details.

\end{itemize}

\sphinxAtStartPar
Many bug fixes, minor changes and documentation improvements are not mentioned
here.


\paragraph{Details of changes in 8.6}
\label{\detokenize{changes:details-of-changes-in-8-6}}
\sphinxAtStartPar
Kernel
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fixed critical bug \#5248 in VM long multiplication on 32\sphinxhyphen{}bit
architectures. Was there only since 8.6beta1, so no stable release impacted.

\end{itemize}

\sphinxAtStartPar
Other bug fixes in universes, type class shelving,...


\paragraph{Details of changes in 8.6.1}
\label{\detokenize{changes:details-of-changes-in-8-6-1}}\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix \#5380: Default colors for CoqIDE are actually applied.

\item {} 
\sphinxAtStartPar
Fix plugin warnings

\item {} 
\sphinxAtStartPar
Document named evars (including Show ident)

\item {} 
\sphinxAtStartPar
Fix Bug \#5574, document function scope

\item {} 
\sphinxAtStartPar
Adding a test case as requested in bug 5205.

\item {} 
\sphinxAtStartPar
Fix Bug \#5568, no dup notation warnings on repeated module imports

\item {} 
\sphinxAtStartPar
Fix documentation of Typeclasses eauto :=

\item {} 
\sphinxAtStartPar
Refactor documentation of records.

\item {} 
\sphinxAtStartPar
Protecting from warnings while compiling 8.6

\item {} 
\sphinxAtStartPar
Fixing an inconsistency between configure and configure.ml

\item {} 
\sphinxAtStartPar
Add test\sphinxhyphen{}suite checks for coqchk with constraints

\item {} 
\sphinxAtStartPar
Fix bug \#5019 (looping zify on dependent types)

\item {} 
\sphinxAtStartPar
Fix bug 5550: "typeclasses eauto with" does not work with section variables.

\item {} 
\sphinxAtStartPar
Bug 5546, qualify datatype constructors when needed in Show Match

\item {} 
\sphinxAtStartPar
Bug \#5535, test for Show with \sphinxhyphen{}emacs

\item {} 
\sphinxAtStartPar
Fix bug \#5486, don't reverse ids in tuples

\item {} 
\sphinxAtStartPar
Fixing \#5522 (anomaly with free vars of pat)

\item {} 
\sphinxAtStartPar
Fix bug \#5526, don't check for nonlinearity in notation if printing only

\item {} 
\sphinxAtStartPar
Fix bug \#5255

\item {} 
\sphinxAtStartPar
Fix bug \#3659: \sphinxhyphen{}time should understand multibyte encodings.

\item {} 
\sphinxAtStartPar
FIx bug \#5300: Anomaly: Uncaught exception Not\_found" in "Print Assumptions".

\item {} 
\sphinxAtStartPar
Fix outdated description in RefMan.

\item {} 
\sphinxAtStartPar
Repairing \sphinxcode{\sphinxupquote{Set Rewriting Schemes}}

\item {} 
\sphinxAtStartPar
Fixing \#5487 (v8.5 regression on ltac\sphinxhyphen{}matching expressions with evars).

\item {} 
\sphinxAtStartPar
Fix description of command\sphinxhyphen{}line arguments for Add (Rec) LoadPath

\item {} 
\sphinxAtStartPar
Fix bug \#5377: @? patterns broken.

\item {} 
\sphinxAtStartPar
add XML protocol doc

\item {} 
\sphinxAtStartPar
Fix anomaly when doing {[}all:Check \_.{]} during a proof.

\item {} 
\sphinxAtStartPar
Correction of bug \#4306

\item {} 
\sphinxAtStartPar
Fix \#5435: {[}Eval native\_compute in{]} raises anomaly.

\item {} 
\sphinxAtStartPar
Instances should obey universe binders even when defined by tactics.

\item {} 
\sphinxAtStartPar
Intern names bound in match patterns

\item {} 
\sphinxAtStartPar
funind: Ignore missing info for current function

\item {} 
\sphinxAtStartPar
Do not typecheck twice the type of opaque constants.

\item {} 
\sphinxAtStartPar
show unused intro pattern warning

\item {} 
\sphinxAtStartPar
{[}future{]} Be eager when "chaining" already resolved future values.

\item {} 
\sphinxAtStartPar
Opaque side effects

\item {} 
\sphinxAtStartPar
Fix \#5132: coq\_makefile generates incorrect install goal

\item {} 
\sphinxAtStartPar
Run non\sphinxhyphen{}tactic comands without resilient\_command

\item {} 
\sphinxAtStartPar
Univs: fix bug \#5365, generation of u+k <= v constraints

\item {} 
\sphinxAtStartPar
make \sphinxcode{\sphinxupquote{emit}} tail recursive

\item {} 
\sphinxAtStartPar
Don't require printing\sphinxhyphen{}only notation to be productive

\item {} 
\sphinxAtStartPar
Fix the way setoid\_rewrite handles bindings.

\item {} 
\sphinxAtStartPar
Fix for bug 5244 \sphinxhyphen{} set printing width ignored when given enough space

\item {} 
\sphinxAtStartPar
Fix bug 4969, autoapply was not tagging shelved subgoals correctly

\end{itemize}


\subsubsection{Version 8.5}
\label{\detokenize{changes:version-8-5}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id945}}
\sphinxAtStartPar
Coq version 8.5 contains the result of five specific long\sphinxhyphen{}term projects:
\begin{itemize}
\item {} 
\sphinxAtStartPar
A new asynchronous evaluation and compilation mode by Enrico Tassi
with help from Bruno Barras and Carst Tankink.

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

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

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

\item {} 
\sphinxAtStartPar
An implementation of primitive projections with
η\sphinxhyphen{}conversion bringing significant performance improvements
when using records by Matthieu Sozeau.

\end{itemize}

\sphinxAtStartPar
The full integration of the proof engine, by Arnaud Spiwack and
Pierre\sphinxhyphen{}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.

\sphinxAtStartPar
The way 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 – with the .vio extension – 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.

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

\sphinxAtStartPar
Carst Tankink developed a Coq back\sphinxhyphen{}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\sphinxhyphen{}ITP French ANR project.

\sphinxAtStartPar
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\sphinxhyphen{}level algorithms
like unification to be entirely type safe. The internal representation
of universes has been modified but this is invisible to the user.

\sphinxAtStartPar
The underlying logic has been extended with η\sphinxhyphen{}conversion for
records defined with primitive projections by Matthieu Sozeau. This
additional form of η\sphinxhyphen{}conversion is justified using the same
principle than the previously added η\sphinxhyphen{}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.

\sphinxAtStartPar
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 \sphinxcode{\sphinxupquote{\sphinxhyphen{}indices\sphinxhyphen{}matter}} has been implemented,
taking into account the universe levels of indices when computing the
levels of inductive types. This supports using Coq as a tool to explore
the relations between homotopy theory and type theory.

\sphinxAtStartPar
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.

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

\sphinxAtStartPar
Pierre Boutillier developed an improved tactic for simplification of
expressions called {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}}.

\sphinxAtStartPar
Maxime Dénès maintained the bytecode\sphinxhyphen{}based reduction machine. Pierre
Letouzey maintained the extraction mechanism.

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

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

\sphinxAtStartPar
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\sphinxhyphen{}Marie Pédrot and
Arnaud Spiwack.

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

\sphinxAtStartPar
The efficiency of the whole system has been significantly improved
thanks to contributions from Pierre\sphinxhyphen{}Marie Pédrot.

\sphinxAtStartPar
A distribution channel for 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.

\sphinxAtStartPar
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.

\sphinxAtStartPar
Many power users helped to improve the design of the new features via
the bug tracker, the coq development mailing list or the Coq\sphinxhyphen{}Club
mailing list. Special thanks are going to the users who contributed
patches and intensive brain\sphinxhyphen{}storming, starting with Jason Gross,
Jonathan Leivent, Greg Malecha, Clément Pit\sphinxhyphen{}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.

\sphinxAtStartPar
Version 8.5 is one of the most important releases of Coq. Its development
spanned over about 3 years and a half with about one year of
beta\sphinxhyphen{}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\sphinxhyphen{}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\sphinxhyphen{}Christophe Filliâtre, Julien Forest, Sébastien Hinderer, Assia
Mahboubi, Jean\sphinxhyphen{}Marc Notin, Yann Régis\sphinxhyphen{}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 Coq development team
\item[] 
\end{DUlineblock}


\paragraph{Potential sources of incompatibilities}
\label{\detokenize{changes:id946}}
\sphinxAtStartPar
List of typical changes to be done to adapt files from Coq 8.4
to Coq 8.5 when not using compatibility option \sphinxcode{\sphinxupquote{\sphinxhyphen{}compat 8.4}}.
\begin{itemize}
\item {} 
\sphinxAtStartPar
Symptom: "The reference omega was not found in the current environment".

\sphinxAtStartPar
Cause: "Require Omega" does not import the tactic "omega" any more

\sphinxAtStartPar
Possible solutions:
\begin{itemize}
\item {} 
\sphinxAtStartPar
use "Require Import OmegaTactic" (not compatible with 8.4)

\item {} 
\sphinxAtStartPar
use "Require Import Omega" (compatible with 8.4)

\item {} 
\sphinxAtStartPar
add definition "Ltac omega := Coq.omega.Omega.omega."

\end{itemize}

\item {} 
\sphinxAtStartPar
Symptom: "intuition" cannot solve a goal (not working anymore on non standard connective)

\sphinxAtStartPar
Cause: "intuition" had an accidental non uniform behavior fixed on non standard connectives

\sphinxAtStartPar
Possible solutions:
\begin{itemize}
\item {} 
\sphinxAtStartPar
use "dintuition" instead; it is stronger than "intuition" and works
uniformly on non standard connectives, such as n\sphinxhyphen{}ary conjunctions or disjunctions
(not compatible with 8.4)

\item {} 
\sphinxAtStartPar
do the script differently

\end{itemize}

\item {} 
\sphinxAtStartPar
Symptom: The constructor foo (in type bar) expects n arguments.

\sphinxAtStartPar
Cause: parameters must now be given in patterns

\sphinxAtStartPar
Possible solutions:
\begin{itemize}
\item {} 
\sphinxAtStartPar
use option "Set Asymmetric Patterns" (compatible with 8.4)

\item {} 
\sphinxAtStartPar
add "\_" for the parameters (not compatible with 8.4)

\item {} 
\sphinxAtStartPar
turn the parameters into implicit arguments (compatible with 8.4)

\end{itemize}

\item {} 
\sphinxAtStartPar
Symptom: "NPeano.Nat.foo" not existing anymore

\sphinxAtStartPar
Possible solutions:
\begin{itemize}
\item {} 
\sphinxAtStartPar
use "Nat.foo" instead

\end{itemize}

\sphinxAtStartPar
Symptom: typing problems with proj1\_sig or similar

\sphinxAtStartPar
Cause: coercion from sig to sigT and similar coercions have been
removed so as to make the initial state easier to understand for
beginners

\sphinxAtStartPar
Solution: change proj1\_sig into projT1 and similarly (compatible with 8.4)

\end{itemize}

\sphinxAtStartPar
Other detailed changes
\begin{itemize}
\item {} 
\sphinxAtStartPar
options for \sphinxstyleemphasis{coq} compilation (see below for ocaml).
\begin{itemize}
\item {} 
\sphinxAtStartPar
{[}\sphinxhyphen{}I foo{]} is now deprecated and will not add directory foo to the
coq load path (only for ocaml, see below). Just replace {[}\sphinxhyphen{}I foo{]} by
{[}\sphinxhyphen{}Q foo ""{]} in your project file and re\sphinxhyphen{}generate makefile. Or
perform the same operation directly in your makefile if you edit it
by hand.

\item {} 
\sphinxAtStartPar
Option \sphinxhyphen{}R Foo bar is the same in v8.5 than in v8.4 concerning coq
load path.

\item {} 
\sphinxAtStartPar
Option {[}\sphinxhyphen{}I foo \sphinxhyphen{}as bar{]} is unchanged but discouraged unless you
compile ocaml code. Use \sphinxhyphen{}Q foo bar instead.

\end{itemize}

\sphinxAtStartPar
for more details: see section "Customization at launch
time" of the reference manual.

\item {} 
\sphinxAtStartPar
Command line options for ocaml  Compilation of ocaml code (plugins)
\begin{itemize}
\item {} 
\sphinxAtStartPar
{[}\sphinxhyphen{}I foo{]} is \sphinxstyleemphasis{not} deprecated to add foo to the ocaml load path.

\item {} 
\sphinxAtStartPar
{[}\sphinxhyphen{}I foo \sphinxhyphen{}as bar{]} adds foo to the ocaml load path \sphinxstyleemphasis{and} adds foo to
the coq load path with logical name bar (shortcut for \sphinxhyphen{}I foo \sphinxhyphen{}Q foo
bar).

\end{itemize}

\sphinxAtStartPar
for more details: section "Customization at launch
time" of the reference manual.

\item {} 
\sphinxAtStartPar
Universe Polymorphism.

\item {} 
\sphinxAtStartPar
Refinement, unification and tactics are now aware of universes,
resulting in more localized errors. Universe inconsistencies
should no more get raised at Qed time but during the proof.
Unification \sphinxstyleemphasis{always} produces well\sphinxhyphen{}typed substitutions, hence
some rare cases of unifications that succeeded while producing
ill\sphinxhyphen{}typed terms before will now fail.

\item {} 
\sphinxAtStartPar
The {[}change p with c{]} tactic semantics changed, now typechecking
{[}c{]} at each matching occurrence {[}t{]} of the pattern {[}p{]}, and
converting {[}t{]} with {[}c{]}.

\item {} 
\sphinxAtStartPar
Template polymorphic inductive types: the partial application
of a template polymorphic type (e.g. list) is not polymorphic.
An explicit parameter application (e.g {[}fun A => list A{]}) or
{[}apply (list \_){]} will result in a polymorphic instance.

\item {} 
\sphinxAtStartPar
The type inference algorithm now takes opacity of constants into
account. This may have effects on tactics using type inference
(e.g. induction). Extra "Transparent" might have to be added to
revert opacity of constants.

\end{itemize}

\sphinxAtStartPar
Type classes.
\begin{itemize}
\item {} 
\sphinxAtStartPar
When writing an \sphinxcode{\sphinxupquote{Instance foo : Class A := \{| proj := t |\}}} (note the
vertical bars), support for typechecking the projections using the
type information and switching to proof mode is no longer available.
Use \sphinxcode{\sphinxupquote{\{ \}}} (without the vertical bars) instead.

\end{itemize}

\sphinxAtStartPar
Tactic abstract.
\begin{itemize}
\item {} 
\sphinxAtStartPar
Auxiliary lemmas generated by the abstract tactic are removed from
the global environment and inlined in the proof term when a proof
is ended with Qed.  The behavior of 8.4 can be obtained by ending
proofs with "Qed exporting" or "Qed exporting ident, .., ident".

\end{itemize}


\paragraph{Details of changes in 8.5beta1}
\label{\detokenize{changes:details-of-changes-in-8-5beta1}}
\sphinxAtStartPar
Logic
\begin{itemize}
\item {} 
\sphinxAtStartPar
Primitive projections for records allow for a compact representation
of projections, without parameters and avoid the behavior of defined
projections that can unfold to a case expression. To turn the use of
native projections on, use {[}Set Primitive Projections{]}. Record,
Class and Structure types defined while this option is set will be
defined with primitive projections instead of the usual encoding as
a case expression. For compatibility, when p is a primitive
projection, @p can be used to refer to the projection with explicit
parameters, i.e. {[}@p{]} is definitionally equal to {[}λ params r. r.(p){]}.
Records with primitive projections have eta\sphinxhyphen{}conversion, the
canonical form being {[}mkR pars (p1 t) ... (pn t){]}.

\item {} 
\sphinxAtStartPar
New universe polymorphism (see reference manual)

\item {} 
\sphinxAtStartPar
New option \sphinxhyphen{}type\sphinxhyphen{}in\sphinxhyphen{}type to collapse the universe hierarchy (this makes the
logic inconsistent).

\item {} 
\sphinxAtStartPar
The guard condition for fixpoints is now a bit stricter. Propagation
of subterm value through pattern matching is restricted according to
the return predicate. Restores compatibility of Coq's logic with the
propositional extensionality axiom. May create incompatibilities in
recursive programs heavily using dependent types.

\item {} 
\sphinxAtStartPar
Trivial inductive types are no longer defined in Type but in Prop, which
leads to a non\sphinxhyphen{}dependent induction principle being generated in place of
the dependent one. To recover the old behavior, explicitly define your
inductive types in Set.

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
A command "Variant" allows to define non\sphinxhyphen{}recursive variant types.

\item {} 
\sphinxAtStartPar
The command "Record foo ..." does not generate induction principles
(foo\_rect, foo\_rec, foo\_ind) anymore by default (feature wish
\#2693). The command "Variant foo ..." does not either. A flag
"Set/Unset Nonrecursive Elimination Schemes" allows changing this.
The tactic "induction" on a "Record" or a "Variant" is now actually
doing "destruct".

\item {} 
\sphinxAtStartPar
The "Open Scope" command can now be given also a delimiter (e.g. Z).

\item {} 
\sphinxAtStartPar
The "Definition" command now allows the "Local" modifier, allowing
for non\sphinxhyphen{}importable definitions. The same goes for "Axiom" and "Parameter".

\item {} 
\sphinxAtStartPar
Section\sphinxhyphen{}specific commands such as "Let" (resp. "Variable", "Hypothesis") used
out of a section now behave like the corresponding "Local" command, i.e.
"Local Definition" (resp. "Local Parameter", "Local Axiom"). (potential source
of rare incompatibilities).

\item {} 
\sphinxAtStartPar
The "Let" command can now define local (co)fixpoints.

\item {} 
\sphinxAtStartPar
Command "Search" has been renamed into "SearchHead". The command
name "Search" now behaves like former "SearchAbout". The latter name
is deprecated.

\item {} 
\sphinxAtStartPar
"Search", "About", "SearchHead", "SearchRewrite" and "SearchPattern"
now search for hypothesis (of the current goal by default) first.
They now also support the goal selector prefix to specify another
goal to search: e.g. "n:Search id". This is also true for
SearchAbout although it is deprecated.

\item {} 
\sphinxAtStartPar
The coq/user\sphinxhyphen{}contrib directory and the XDG directories are no longer
recursively added to the load path, so files from installed libraries
now need to be fully qualified for the "Require" command to find them.
The tools/update\sphinxhyphen{}require script can be used to convert a development.

\item {} 
\sphinxAtStartPar
A new Print Strategies command allows visualizing the opacity status
of the whole engine.

\item {} 
\sphinxAtStartPar
The "Locate" command now searches through all sorts of qualified namespaces of
Coq: terms, modules, tactics, etc. The old behavior of the command can be
retrieved using the "Locate Term" command.

\item {} 
\sphinxAtStartPar
New "Derive" command to help writing program by derivation.

\item {} 
\sphinxAtStartPar
New "Refine Instance Mode" option that allows to deactivate the generation of
obligations in incomplete typeclass instances, raising an error instead.

\item {} 
\sphinxAtStartPar
"Collection" command to name sets of section hypotheses.  Named collections
can be used in the syntax of "Proof using" to assert which section variables
are used in a proof.

\item {} 
\sphinxAtStartPar
The "Optimize Proof" command can be placed in the middle of a proof to
force the compaction of the data structure used to represent the ongoing
proof (evar map). This may result in a lower memory footprint and speed up
the execution of the following tactics.

\item {} 
\sphinxAtStartPar
"Optimize Heap" command to tell the OCaml runtime to perform a major
garbage collection step and heap compaction.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Instance}} no longer treats the \sphinxcode{\sphinxupquote{\{|...|\}}} syntax specially; it handles it
in the same way as other commands, e.g. "Definition". Use the \sphinxcode{\sphinxupquote{\{...\}}}
syntax (no pipe symbols) to recover the old behavior.

\end{itemize}

\sphinxAtStartPar
Specification Language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Slight changes in unification error messages.

\item {} 
\sphinxAtStartPar
Added a syntax \$(...)\$ that allows putting tactics in terms (may
break user notations using "\$(", fixable by inserting a space or
rewriting the notation).

\item {} 
\sphinxAtStartPar
Constructors in pattern\sphinxhyphen{}matching patterns now respect the same rules
regarding implicit arguments as in applicative position. The old
behavior can be recovered by the command "Set Asymmetric
Patterns". As a side effect, notations for constructors explicitly
mentioning non\sphinxhyphen{}implicit parameters can now be used in patterns.
Considering that the pattern language is already rich enough, binding
local definitions is however now forbidden in patterns (source of
incompatibilities for local definitions that delta\sphinxhyphen{}reduce to a constructor).

\item {} 
\sphinxAtStartPar
Type inference algorithm now granting opacity of constants. This might also
affect behavior of tactics (source of incompatibilities, solvable by
re\sphinxhyphen{}declaring transparent constants which were set opaque).

\item {} 
\sphinxAtStartPar
Existential variables are now referred to by an identifier and the
relevant part of their instance is displayed by default. They can be
reparsed. The naming policy is yet unstable and subject to changes
in future releases.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New tactic engine allowing dependent subgoals, fully backtracking
(also known as multiple success) tactics, as well as tactics which
can consider multiple goals together. In the new tactic engine,
instantiation information of existential variables is always
propagated to tactics, removing the need to manually use the
"instantiate" tactics to mark propagation points.
\begin{itemize}
\item {} 
\sphinxAtStartPar
New tactical (a+b) inserts a backtracking point. When (a+b);c fails
during the execution of c, it can backtrack and try b instead of a.

\item {} 
\sphinxAtStartPar
New tactical (once a) removes all the backtracking points from a
(i.e. it selects the first success of a).

\item {} 
\sphinxAtStartPar
Tactic "constructor" is now fully backtracking. In case of
incompatibilities (e.g. combinatoric explosion), the former
behavior of "constructor" can be retrieved by using instead
"{[}> once constructor ..{]}". Thanks to backtracking, undocumented
"constructor <tac>" syntax is now equivalent to
"{[}> once (constructor; tac) ..{]}".

\item {} 
\sphinxAtStartPar
New "multimatch" variant of "match" tactic which backtracks to
new branches in case of a later failure. The "match" tactic is
equivalent to "once multimatch".

\item {} 
\sphinxAtStartPar
New selector "all:" such that "all:tac" applies tactic "tac" to
all the focused goals, instead of just the first one as is the
default.

\item {} 
\sphinxAtStartPar
A corresponding new option Set Default Goal Selector "all" makes
the tactics in scripts be applied to all the focused goal by default

\item {} 
\sphinxAtStartPar
New selector "par:" such that "par:tac" applies the (terminating)
tactic "tac" to all the focused goal in parallel. The number of worker
can be selected with \sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}tac\sphinxhyphen{}j and also limited using the
coqworkmgr utility.

\item {} 
\sphinxAtStartPar
New tactics "revgoals", "cycle" and "swap" to reorder goals.

\item {} 
\sphinxAtStartPar
The semantics of recursive tactics (introduced with "Ltac t := ..."
or "let rec t := ... in ...") changed slightly as t is now
applied to every goal, not each goal independently. In particular
it may be applied when no goals are left. This may cause tactics
such as "let rec t := constructor;t" to loop indefinitely. The
simple fix is to rewrite the recursive calls as follows:
"let rec t := constructor;{[}t..{]}" which recovers the earlier behavior
(source of rare incompatibilities).

\item {} 
\sphinxAtStartPar
New tactic language feature "numgoals" to count number of goals. It is
accompanied by a "guard" tactic which fails if a Boolean test over
integers does not pass.

\item {} 
\sphinxAtStartPar
New tactical "{[}> ... {]}" to apply tactics to individual goals.

\item {} 
\sphinxAtStartPar
New tactic "gfail" which works like "fail" except it will also
fail if every goal has been solved.

\item {} 
\sphinxAtStartPar
The refine tactic is changed not to use an ad hoc typing algorithm
to generate subgoals. It also uses the dependent subgoal feature
to generate goals to materialize every existential variable which
is introduced by the refinement (source of incompatibilities).

\item {} 
\sphinxAtStartPar
A tactic shelve is introduced to manage the subgoals which may be
solved by unification: shelve removes every goal it is applied to
from focus. These goals can later be called back into focus by the
Unshelve command.

\item {} 
\sphinxAtStartPar
A variant shelve\_unifiable only removes those goals which appear
as existential variables in other goals. To emulate the old
refine, use "refine c;shelve\_unifiable". This can still cause
incompatibilities in rare occasions.

\item {} 
\sphinxAtStartPar
New "give\_up" tactic to skip over a goal.  A proof containing
given up goals cannot be closed with "Qed", but only with "Admitted".

\end{itemize}

\item {} 
\sphinxAtStartPar
The implementation of the admit tactic has changed: no axiom is
generated for the admitted sub proof. "admit" is now an alias for
"give\_up".  Code relying on this specific behavior of "admit"
can be made to work by:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Adding an "Axiom" for each admitted subproof.

\item {} 
\sphinxAtStartPar
Adding a single "Axiom proof\_admitted : False." and the Ltac definition
"Ltac admit := case proof\_admitted.".

\end{itemize}

\item {} 
\sphinxAtStartPar
Matching using "lazymatch" was fundamentally modified. It now behaves
like "match" (immediate execution of the matching branch) but without
the backtracking mechanism in case of failure.

\item {} 
\sphinxAtStartPar
New "tryif t then u else v" tactical which executes "u" in case of success
of "t" and "v" in case of failure.

\item {} 
\sphinxAtStartPar
New conversion tactic "native\_compute": evaluates the goal (or an hypothesis)
with a call\sphinxhyphen{}by\sphinxhyphen{}value strategy, using the OCaml native compiler. Useful on
very intensive computations.

\item {} 
\sphinxAtStartPar
New "cbn" tactic, a well\sphinxhyphen{}behaved simpl.

\item {} 
\sphinxAtStartPar
Repeated identical calls to omega should now produce identical proof terms.

\item {} 
\sphinxAtStartPar
Tactics btauto, a reflexive Boolean tautology solver.

\item {} 
\sphinxAtStartPar
Tactic "tauto" was exceptionally able to destruct other connectives
than the binary connectives "and", "or", "prod", "sum", "iff". This
non\sphinxhyphen{}uniform behavior has been fixed (bug \#2680) and tauto is
slightly weaker (possible source of incompatibilities). On the
opposite side, new tactic "dtauto" is able to destruct any
record\sphinxhyphen{}like inductive types, superseding the old version of "tauto".

\item {} 
\sphinxAtStartPar
Similarly, "intuition" has been made more uniform and, where it now
fails, "dintuition" can be used (possible source of incompatibilities).

\item {} 
\sphinxAtStartPar
New option "Unset Intuition Negation Unfolding" for deactivating automatic
unfolding of "not" in intuition.

\item {} 
\sphinxAtStartPar
Tactic notations can now be defined locally to a module (use "Local" prefix).

\item {} 
\sphinxAtStartPar
Tactic "red" now reduces head beta\sphinxhyphen{}iota redexes (potential source of
rare incompatibilities).

\item {} 
\sphinxAtStartPar
Tactic "hnf" now reduces inner beta\sphinxhyphen{}iota redexes
(potential source of rare incompatibilities).

\item {} 
\sphinxAtStartPar
Tactic "intro H" now reduces beta\sphinxhyphen{}iota redexes if these hide a product
(potential source of rare incompatibilities).

\item {} 
\sphinxAtStartPar
In Ltac matching on patterns of the form "\_ pat1 ... patn" now
behaves like if matching on "?X pat1 ... patn", i.e. accepting "\_"
to be instantiated by an applicative term (experimental at this
stage, potential source of incompatibilities).

\item {} 
\sphinxAtStartPar
In Ltac matching on goal, types of hypotheses are now interpreted in
the \%type scope (possible source of incompatibilities).

\item {} 
\sphinxAtStartPar
"change ... in ..." and "simpl ... in ..." now properly consider nested
occurrences (possible source of incompatibilities since this alters
the numbering of occurrences), but do not support nested occurrences.

\item {} 
\sphinxAtStartPar
Tactics simpl, vm\_compute and native\_compute can be given a notation string
to a constant as argument.

\item {} 
\sphinxAtStartPar
When given a reference as argument, simpl, vm\_compute and
native\_compute now strictly interpret it as the head of a pattern
starting with this reference.

\item {} 
\sphinxAtStartPar
The "change p with c" tactic semantics changed, now type checking
"c" at each matching occurrence "t" of the pattern "p", and
converting "t" with "c".

\item {} 
\sphinxAtStartPar
Now "appcontext" and "context" behave the same. The old buggy behavior of
"context" can be retrieved at parse time by setting the
"Tactic Compat Context" flag (possible source of incompatibilities).

\item {} 
\sphinxAtStartPar
New introduction pattern p/c which applies lemma c on the fly on the
hypothesis under consideration before continuing with introduction pattern p.

\item {} 
\sphinxAtStartPar
New introduction pattern {[}= x1 .. xn{]} applies "injection as {[}x1 .. xn{]}"
on the fly if injection is applicable to the hypothesis under consideration
(idea borrowed from Georges Gonthier). Introduction pattern {[}={]} applies
"discriminate" if a discriminable equality.

\item {} 
\sphinxAtStartPar
New introduction patterns * and ** to respectively introduce all forthcoming
dependent variables and all variables/hypotheses dependent or not.

\item {} 
\sphinxAtStartPar
Tactic "injection c as ipats" now clears c if c refers to an
hypothesis and moves the resulting equations in the hypotheses
independently of the number of ipats, which has itself to be less
than the number of new hypotheses (possible source of incompatibilities;
former behavior obtainable by "Unset Injection L2R Pattern Order").

\item {} 
\sphinxAtStartPar
Tactic "injection" now automatically simplifies subgoals
"existT n p = existT n p'" into "p = p'" when "n" is in an inductive type for
which a decidable equality scheme has been generated with "Scheme Equality"
(possible source of incompatibilities).

\item {} 
\sphinxAtStartPar
New tactic "rewrite\_strat" for generalized rewriting with user\sphinxhyphen{}defined
strategies, subsuming autorewrite.

\item {} 
\sphinxAtStartPar
Injection can now also deduce equality of arguments of sort Prop, by using
the option "Set Injection On Proofs" (disabled by default). Also improved the
error messages.

\item {} 
\sphinxAtStartPar
Tactic "subst id" now supports id occurring in dependent local definitions.

\item {} 
\sphinxAtStartPar
Bugs fixed about intro\sphinxhyphen{}pattern "*" might lead to some rare incompatibilities.

\item {} 
\sphinxAtStartPar
New tactical "time" to display time spent executing its argument.

\item {} 
\sphinxAtStartPar
Tactics referring or using a constant dependent in a section variable which
has been cleared or renamed in the current goal context now fail
(possible source of incompatibilities solvable by avoiding clearing
the relevant hypotheses).

\item {} 
\sphinxAtStartPar
New construct "uconstr:c" and "type\_term c" to build untyped terms.

\item {} 
\sphinxAtStartPar
Binders in terms defined in Ltac (either "constr" or "uconstr") can
now take their names from identifiers defined in Ltac. As a
consequence, a name cannot be used in a binder "constr:(fun x =>
...)" if an Ltac variable of that name already exists and does not
contain an identifier. Source of occasional incompatibilities.

\item {} 
\sphinxAtStartPar
The "refine" tactic now accepts untyped terms built with "uconstr"
so that terms with holes can be constructed piecewise in Ltac.

\item {} 
\sphinxAtStartPar
New bullets \sphinxhyphen{}\sphinxhyphen{}, ++, \sphinxstylestrong{, \sphinxhyphen{}\sphinxhyphen{}\sphinxhyphen{}, +++, *}, ... made available.

\item {} 
\sphinxAtStartPar
More informative messages when wrong bullet is used.

\item {} 
\sphinxAtStartPar
Bullet suggestion when a subgoal is solved.

\item {} 
\sphinxAtStartPar
New tactic "enough", symmetric to "assert", but with subgoals
swapped, as a more friendly replacement of "cut".

\item {} 
\sphinxAtStartPar
In destruct/induction, experimental modifier "!" prefixing the
hypothesis name to tell not erasing the hypothesis.

\item {} 
\sphinxAtStartPar
Bug fixes in "inversion as" may occasionally lead to incompatibilities.

\item {} 
\sphinxAtStartPar
Behavior of introduction patterns \sphinxhyphen{}> and <\sphinxhyphen{} made more uniform
(hypothesis is cleared, rewrite in hypotheses and conclusion and
erasing the variable when rewriting a variable).

\item {} 
\sphinxAtStartPar
New experimental option "Set Standard Proposition Elimination Names"
so that case analysis or induction on schemes in Type containing
propositions now produces "H"\sphinxhyphen{}based names.

\item {} 
\sphinxAtStartPar
Tactics from plugins are now active only when the corresponding module
is imported (source of incompatibilities, solvable by adding an "Import";
in the particular case of Omega, use "Require Import OmegaTactic").

\item {} 
\sphinxAtStartPar
Semantics of destruct/induction has been made more regular in some
edge cases, possibly leading to incompatibilities:
\begin{itemize}
\item {} 
\sphinxAtStartPar
new goals are now opened when the term does not match a subterm of
the goal and has unresolved holes, while in 8.4 these holes were
turned into existential variables

\item {} 
\sphinxAtStartPar
when no "at" option is given, the historical semantics which
selects all subterms syntactically identical to the first subterm
matching the given pattern is used

\item {} 
\sphinxAtStartPar
non\sphinxhyphen{}dependent destruct/induction on an hypothesis with premises in
an inductive type with indices is fixed

\item {} 
\sphinxAtStartPar
residual local definitions are now correctly removed.

\end{itemize}

\item {} 
\sphinxAtStartPar
The rename tactic may now replace variables in parallel.

\item {} 
\sphinxAtStartPar
A new "Info" command replaces the "info" tactical discontinued in
v8.4. It still gives informative results in many cases.

\item {} 
\sphinxAtStartPar
The "info\_auto" tactic is known to be broken and does not print a
trace anymore. Use "Info 1 auto" instead. The same goes for
"info\_trivial". On the other hand "info\_eauto" still works fine,
while "Info 1 eauto" prints a trivial trace.

\item {} 
\sphinxAtStartPar
When using a lemma of the prototypical form "forall A, \{a:A \& P a\}",
"apply" and "apply in" do not instantiate anymore "A" with the
current goal and use "a" as the proof, as they were sometimes doing,
now considering that it is a too powerful decision.

\end{itemize}

\sphinxAtStartPar
Program
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Solve Obligations using" changed to "Solve Obligations with",
consistent with "Proof with".

\item {} 
\sphinxAtStartPar
Program Lemma, Definition now respect automatic introduction.

\item {} 
\sphinxAtStartPar
Program Lemma, Definition, etc.. now interpret "\sphinxhyphen{}>" like Lemma and
Definition as a non\sphinxhyphen{}dependent arrow (potential source of
incompatibility).

\item {} 
\sphinxAtStartPar
Add/document "Set Hide Obligations" (to hide obligations in the final
term inside an implicit argument) and "Set Shrink Obligations" (to
minimize dependencies of obligations defined by tactics).

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
The syntax "x \sphinxhyphen{}> y" is now declared at level 99. In particular, it has
now a lower priority than "<\sphinxhyphen{}>": "A \sphinxhyphen{}> B <\sphinxhyphen{}> C" is now "A \sphinxhyphen{}> (B <\sphinxhyphen{}> C)"
(possible source of incompatibilities)

\item {} 
\sphinxAtStartPar
Notations accept term\sphinxhyphen{}providing tactics using the \$(...)\$ syntax.

\item {} 
\sphinxAtStartPar
"Bind Scope" can no longer bind "Funclass" and "Sortclass".

\item {} 
\sphinxAtStartPar
A notation can be given a (compat "8.x") annotation, making it behave
like a "only parsing" notation, but the annotation may lead to eventually
issue warnings or errors in further versions when this notation is used.

\item {} 
\sphinxAtStartPar
More systematic insertion of spaces as a default for printing
notations ("format" still available to override the default).

\item {} 
\sphinxAtStartPar
In notations, a level modifier referring to a non\sphinxhyphen{}existent variable is
now considered an error rather than silently ignored.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Option \sphinxhyphen{}I now only adds directories to the ml path.

\item {} 
\sphinxAtStartPar
Option \sphinxhyphen{}Q behaves as \sphinxhyphen{}R, except that the logical path of any loaded file has
to be fully qualified.

\item {} 
\sphinxAtStartPar
Option \sphinxhyphen{}R no longer adds recursively to the ml path; only the root
directory is added. (Behavior with respect to the load path is
unchanged.)

\item {} 
\sphinxAtStartPar
Option \sphinxhyphen{}nois prevents coq/theories and coq/plugins to be recursively
added to the load path. (Same behavior as with coq/user\sphinxhyphen{}contrib.)

\item {} 
\sphinxAtStartPar
coqdep accepts a \sphinxhyphen{}dumpgraph option generating a dot file.

\item {} 
\sphinxAtStartPar
Makefiles generated through coq\_makefile have three new targets "quick"
"checkproofs" and "vio2vo", allowing respectively to asynchronously compile
the files without playing the proof scripts, asynchronously checking
that the quickly generated proofs are correct and generating the object
files from the quickly generated proofs.

\item {} 
\sphinxAtStartPar
The XML plugin was discontinued and removed from the source.

\item {} 
\sphinxAtStartPar
A new utility called coqworkmgr can be used to limit the number of
concurrent workers started by independent processes, like make and CoqIDE.
This is of interest for users of the par: goal selector.

\end{itemize}

\sphinxAtStartPar
Interfaces
\begin{itemize}
\item {} 
\sphinxAtStartPar
CoqIDE supports asynchronous edition of the document, ongoing tasks and
errors are reported in the bottom right window.  The number of workers
taking care of processing proofs can be selected with \sphinxhyphen{}async\sphinxhyphen{}proofs\sphinxhyphen{}j.

\item {} 
\sphinxAtStartPar
CoqIDE highlights in yellow "unsafe" commands such as axiom
declarations, and tactics like "give\_up".

\item {} 
\sphinxAtStartPar
CoqIDE supports Proof General like key bindings;
to activate the PG mode go to Edit \sphinxhyphen{}> Preferences \sphinxhyphen{}> Editor.
For the documentation see Help \sphinxhyphen{}> Help for PG mode.

\item {} 
\sphinxAtStartPar
CoqIDE automatically retracts the locked area when one edits the
locked text.

\item {} 
\sphinxAtStartPar
CoqIDE search and replace got regular expressions power. See the
documentation of OCaml's Str module for the supported syntax.

\item {} 
\sphinxAtStartPar
Many CoqIDE windows, including the query one, are now detachable to
improve usability on multi screen work stations.

\item {} 
\sphinxAtStartPar
Coqtop/coqc outputs highlighted syntax. Colors can be configured thanks
to the COQ\_COLORS environment variable, and their current state can
be displayed with the \sphinxhyphen{}list\sphinxhyphen{}tags command line option.

\item {} 
\sphinxAtStartPar
Third party user interfaces can install their main loop in \$COQLIB/toploop
and call coqtop with the \sphinxhyphen{}toploop flag to select it.

\end{itemize}

\sphinxAtStartPar
Internal Infrastructure
\begin{itemize}
\item {} 
\sphinxAtStartPar
Many reorganizations in the ocaml source files. For instance,
many internal a.s.t. of Coq are now placed in mli files in
a new directory intf/, for instance constrexpr.mli or glob\_term.mli.
More details in dev/doc/changes.

\item {} 
\sphinxAtStartPar
The file states/initial.coq does not exist anymore. Instead, coqtop
initially does a "Require" of Prelude.vo (or nothing when given
the options \sphinxhyphen{}noinit or \sphinxhyphen{}nois).

\item {} 
\sphinxAtStartPar
The format of vo files has slightly changed: cf final comments in
checker/cic.mli.

\item {} 
\sphinxAtStartPar
The build system does not produce anymore programs named coqtop.opt
and a symbolic link to coqtop. Instead, coqtop is now directly
an executable compiled with the best OCaml compiler available.
The bytecode program coqtop.byte is still produced. Same for other
utilities.

\item {} 
\sphinxAtStartPar
Some options of the ./configure script slightly changed:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The \sphinxhyphen{}coqrunbyteflags and its blank\sphinxhyphen{}separated argument is replaced
by option \sphinxhyphen{}vmbyteflags which expects a comma\sphinxhyphen{}separated argument.

\item {} 
\sphinxAtStartPar
The \sphinxhyphen{}coqtoolsbyteflags option is discontinued, see \sphinxhyphen{}no\sphinxhyphen{}custom instead.

\end{itemize}

\end{itemize}

\sphinxAtStartPar
Miscellaneous
\begin{itemize}
\item {} 
\sphinxAtStartPar
ML plugins now require a "DECLARE PLUGIN "foo"" statement. The "foo" name
must be exactly the name of the ML module that will be loaded through a
"Declare ML "foo"" command.

\end{itemize}


\paragraph{Details of changes in 8.5beta2}
\label{\detokenize{changes:details-of-changes-in-8-5beta2}}
\sphinxAtStartPar
Logic
\begin{itemize}
\item {} 
\sphinxAtStartPar
The VM now supports inductive types with up to 8388851 non\sphinxhyphen{}constant
constructors and up to 8388607 constant ones.

\end{itemize}

\sphinxAtStartPar
Specification language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Syntax "\$(tactic)\$" changed to "ltac: tactic".

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
A script using the admit tactic can no longer be concluded by either
Qed or Defined. In the first case, Admitted can be used instead. In
the second case, a subproof should be used.

\item {} 
\sphinxAtStartPar
The easy tactic and the now tactical now have a more predictable
behavior, but they might now discharge some previously unsolved goals.

\end{itemize}

\sphinxAtStartPar
Extraction
\begin{itemize}
\item {} 
\sphinxAtStartPar
Definitions extracted to Haskell GHC should no longer randomly
segfault when some Coq types cannot be represented by Haskell types.

\item {} 
\sphinxAtStartPar
Definitions can now be extracted to Json for post\sphinxhyphen{}processing.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Option \sphinxhyphen{}I \sphinxhyphen{}as has been removed, and option \sphinxhyphen{}R \sphinxhyphen{}as has been
deprecated. In both cases, option \sphinxhyphen{}R can be used instead.

\item {} 
\sphinxAtStartPar
coq\_makefile now generates double\sphinxhyphen{}colon rules for rules such as clean.

\end{itemize}

\sphinxAtStartPar
API
\begin{itemize}
\item {} 
\sphinxAtStartPar
The interface of {[}change{]} has changed to take a {[}change\_arg{]}, which
can be built from a {[}constr{]} using {[}make\_change\_arg{]}.

\end{itemize}


\paragraph{Details of changes in 8.5beta3}
\label{\detokenize{changes:details-of-changes-in-8-5beta3}}
\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
New command "Redirect" to redirect the output of a command to a file.

\item {} 
\sphinxAtStartPar
New command "Undelimit Scope" to remove the delimiter of a scope.

\item {} 
\sphinxAtStartPar
New option "Strict Universe Declaration", set by default. It enforces the
declaration of all polymorphic universes appearing in a definition when
introducing it.

\item {} 
\sphinxAtStartPar
New command "Show id" to show goal named id.

\item {} 
\sphinxAtStartPar
Option "Virtual Machine" removed.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New flag "Regular Subst Tactic" which fixes "subst" in situations where
it failed to substitute all substitutable equations or failed to simplify
cycles, or accidentally unfolded local definitions (flag is off by default).

\item {} 
\sphinxAtStartPar
New flag "Loose Hint Behavior" to handle hints loaded but not imported in a
special way. It accepts three distinct flags:
* "Lax", which is the default one, sets the old behavior, i.e. a non\sphinxhyphen{}imported
hint behaves the same as an imported one.
* "Warn" outputs a warning when a non\sphinxhyphen{}imported hint is used. Note that this is
an over\sphinxhyphen{}approximation, because a hint may be triggered by an eauto run that
will eventually fail and backtrack.
* "Strict" changes the behavior of an unloaded hint to the one of the fail
tactic, allowing to emulate the hopefully future import\sphinxhyphen{}scoped hint mechanism.

\item {} 
\sphinxAtStartPar
New compatibility flag "Universal Lemma Under Conjunction" which
let tactics working under conjunctions apply sublemmas of the form
"forall A, ... \sphinxhyphen{}> A".

\item {} 
\sphinxAtStartPar
New compatibility flag "Bracketing Last Introduction Pattern" which can be
set so that the last disjunctive\sphinxhyphen{}conjunctive introduction pattern given to
"intros" automatically complete the introduction of its subcomponents, as the
the disjunctive\sphinxhyphen{}conjunctive introduction patterns in non\sphinxhyphen{}terminal position
already do.

\item {} 
\sphinxAtStartPar
New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
tactical w.r.t. variables appearing in the body of the proof.

\end{itemize}

\sphinxAtStartPar
Program
\begin{itemize}
\item {} 
\sphinxAtStartPar
The "Shrink Obligations" flag now applies to all obligations, not only those
solved by the automatic tactic.

\item {} 
\sphinxAtStartPar
Importing Program no longer overrides the "exists" tactic (potential source
of incompatibilities).

\item {} 
\sphinxAtStartPar
Hints costs are now correctly taken into account (potential source of
incompatibilities).

\item {} 
\sphinxAtStartPar
Documented the Hint Cut command that allows control of the
proof search during typeclass resolution (see reference manual).

\end{itemize}

\sphinxAtStartPar
API
\begin{itemize}
\item {} 
\sphinxAtStartPar
Some functions from pretyping/typing.ml and their derivatives were potential
source of evarmap leaks, as they dropped their resulting evarmap. The
situation was clarified by renaming them according to a \sphinxcode{\sphinxupquote{unsafe\_*}} scheme. Their
sound variant is likewise renamed to their old name. The following renamings
were made.
\begin{itemize}
\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Typing.type\_of}} \sphinxhyphen{}> \sphinxcode{\sphinxupquote{unsafe\_type\_of}}

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Typing.e\_type\_of}} \sphinxhyphen{}> \sphinxcode{\sphinxupquote{type\_of}}

\item {} 
\sphinxAtStartPar
A new \sphinxcode{\sphinxupquote{e\_type\_of}} function that matches the \sphinxcode{\sphinxupquote{e\_}} prefix policy

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{Tacmach.pf\_type\_of}} \sphinxhyphen{}> \sphinxcode{\sphinxupquote{pf\_unsafe\_type\_of}}

\item {} 
\sphinxAtStartPar
A new safe \sphinxcode{\sphinxupquote{pf\_type\_of}} function.

\end{itemize}

\sphinxAtStartPar
All uses of \sphinxcode{\sphinxupquote{unsafe\_*}} functions should be eventually eliminated.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added an option \sphinxhyphen{}w to control the output of coqtop warnings.

\item {} 
\sphinxAtStartPar
Configure now takes an optional \sphinxhyphen{}native\sphinxhyphen{}compiler (yes|no) flag replacing
\sphinxhyphen{}no\sphinxhyphen{}native\sphinxhyphen{}compiler. The new flag is set to no by default under Windows.

\item {} 
\sphinxAtStartPar
Flag \sphinxhyphen{}no\sphinxhyphen{}native\sphinxhyphen{}compiler was removed and became the default for coqc. If
precompilation of files for native conversion test is desired, use
\sphinxhyphen{}native\sphinxhyphen{}compiler.

\item {} 
\sphinxAtStartPar
The \sphinxhyphen{}compile command\sphinxhyphen{}line option now takes the full path of the considered
file, including the ".v" extension, and outputs a warning if such an extension
is lacking.

\item {} 
\sphinxAtStartPar
The \sphinxhyphen{}require and \sphinxhyphen{}load\sphinxhyphen{}vernac\sphinxhyphen{}object command\sphinxhyphen{}line options now take a logical
path of a given library rather than a physical path, thus they behave like
Require {[}Import{]} path.

\item {} 
\sphinxAtStartPar
The \sphinxhyphen{}vm command\sphinxhyphen{}line option has been removed.

\end{itemize}

\sphinxAtStartPar
Standard Library
\begin{itemize}
\item {} 
\sphinxAtStartPar
There is now a Coq.Compat.Coq84 library, which sets the various compatibility
options and does a few redefinitions to make Coq behave more like Coq v8.4.
The standard way of putting Coq in v8.4 compatibility mode is to pass the command
line flags "\sphinxhyphen{}require Coq.Compat.Coq84 \sphinxhyphen{}compat 8.4".

\end{itemize}


\paragraph{Details of changes in 8.5}
\label{\detokenize{changes:details-of-changes-in-8-5}}
\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Flag "\sphinxhyphen{}compat 8.4" now loads Coq.Compat.Coq84. The standard way of
putting Coq in v8.4 compatibility mode is to pass the command line flag
"\sphinxhyphen{}compat 8.4". It can be followed by "\sphinxhyphen{}require Coq.Compat.AdmitAxiom"
if the 8.4 behavior of admit is needed, in which case it uses an axiom.

\end{itemize}

\sphinxAtStartPar
Specification language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Syntax "\$(tactic)\$" changed to "ltac:(tactic)".

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Syntax "destruct !hyp" changed to "destruct (hyp)", and similarly
for induction (rare source of incompatibilities easily solvable by
removing parentheses around "hyp" when not for the purpose of keeping
the hypothesis).

\item {} 
\sphinxAtStartPar
Syntax "p/c" for on\sphinxhyphen{}the\sphinxhyphen{}fly application of a lemma c before
introducing along pattern p changed to p\%c1..\%cn. The feature and
syntax are in experimental stage.

\item {} 
\sphinxAtStartPar
"Proof using" does not clear unused section variables.

\item {} 
\sphinxAtStartPar
Tactic "refine" has been changed back to the 8.4 behavior of shelving subgoals
that occur in other subgoals. The "refine" tactic of 8.5beta3 has been
renamed "simple refine"; it does not shelve any subgoal.

\item {} 
\sphinxAtStartPar
New tactical "unshelve tac" which grab existential variables put on
the tactic shelve by the execution of "tac".

\end{itemize}


\paragraph{Details of changes in 8.5pl1}
\label{\detokenize{changes:details-of-changes-in-8-5pl1}}
\sphinxAtStartPar
Critical bugfix
\begin{itemize}
\item {} 
\sphinxAtStartPar
The subterm relation for the guard condition was incorrectly defined on
primitive projections (\#4588)

\end{itemize}

\sphinxAtStartPar
Plugin development tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
add a .merlin target to the makefile

\end{itemize}

\sphinxAtStartPar
Various performance improvements (time, space used by .vo files)

\sphinxAtStartPar
Other bugfixes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix order of arguments to Big.compare\_case in ExtrOcamlZBigInt.v

\item {} 
\sphinxAtStartPar
Added compatibility coercions from Specif.v which were present in Coq 8.4.

\item {} 
\sphinxAtStartPar
Fixing a source of inefficiency and an artificial dependency in the printer in the congruence tactic.

\item {} 
\sphinxAtStartPar
Allow to unset the refinement mode of Instance in ML

\item {} 
\sphinxAtStartPar
Fixing an incorrect use of prod\_appvect on a term which was not a product in setoid\_rewrite.

\item {} 
\sphinxAtStartPar
Add \sphinxhyphen{}compat 8.4 econstructor tactics, and tests

\item {} 
\sphinxAtStartPar
Add compatibility Nonrecursive Elimination Schemes

\item {} 
\sphinxAtStartPar
Fixing the "No applicable tactic" non informative error message regression on apply.

\item {} 
\sphinxAtStartPar
Univs: fix get\_current\_context (bug \#4603, part I)

\item {} 
\sphinxAtStartPar
Fix a bug in Program coercion code

\item {} 
\sphinxAtStartPar
Fix handling of arity of definitional classes.

\item {} 
\sphinxAtStartPar
\#4630: Some tactics are 20x slower in 8.5 than 8.4.

\item {} 
\sphinxAtStartPar
\#4627: records with no declared arity can be template polymorphic.

\item {} 
\sphinxAtStartPar
\#4623: set tactic too weak with universes (regression)

\item {} 
\sphinxAtStartPar
Fix incorrect behavior of CS resolution

\item {} 
\sphinxAtStartPar
\#4591: Uncaught exception in directory browsing.

\item {} 
\sphinxAtStartPar
CoqIDE is more resilient to initialization errors.

\item {} 
\sphinxAtStartPar
\#4614: "Fully check the document" is uninterruptible.

\item {} 
\sphinxAtStartPar
Try eta\sphinxhyphen{}expansion of records only on non\sphinxhyphen{}recursive ones

\item {} 
\sphinxAtStartPar
Fix bug when a sort is ascribed to a Record

\item {} 
\sphinxAtStartPar
Primitive projections: protect kernel from erroneous definitions.

\item {} 
\sphinxAtStartPar
Fixed bug \#4533 with previous Keyed Unification commit

\item {} 
\sphinxAtStartPar
Win: kill unreliable hence do not waitpid after kill \sphinxhyphen{}9 (Close \#4369)

\item {} 
\sphinxAtStartPar
Fix strategy of Keyed Unification

\item {} 
\sphinxAtStartPar
\#4608: Anomaly "output\_value: abstract value (outside heap)".

\item {} 
\sphinxAtStartPar
\#4607: do not read native code files if native compiler was disabled.

\item {} 
\sphinxAtStartPar
\#4105: poor escaping in the protocol between CoqIDE and coqtop.

\item {} 
\sphinxAtStartPar
\#4596: {[}rewrite{]} broke in the past few weeks.

\item {} 
\sphinxAtStartPar
\#4533 (partial): respect declared global transparency of projections in unification.ml

\item {} 
\sphinxAtStartPar
\#4544: Backtrack on using full betaiota reduction during keyed unification.

\item {} 
\sphinxAtStartPar
\#4540: CoqIDE bottom progress bar does not update.

\item {} 
\sphinxAtStartPar
Fix regression from 8.4 in reflexivity

\item {} 
\sphinxAtStartPar
\#4580: {[}Set Refine Instance Mode{]} also used for Program Instance.

\item {} 
\sphinxAtStartPar
\#4582: cannot override notation {[} x {]}. MAY CREATE INCOMPATIBILITIES, see \#4683.

\item {} 
\sphinxAtStartPar
STM: Print/Extraction have to be skipped if \sphinxhyphen{}quick

\item {} 
\sphinxAtStartPar
\#4542: CoqIDE: STOP button also stops workers

\item {} 
\sphinxAtStartPar
STM: classify some variants of Instance as regular `` \sphinxcode{\sphinxupquote{Fork `}} nodes.

\item {} 
\sphinxAtStartPar
\#4574: Anomaly: Uncaught exception Invalid\_argument("splay\_arity").

\item {} 
\sphinxAtStartPar
Do not give a name to anonymous evars anymore. See bug \#4547.

\item {} 
\sphinxAtStartPar
STM: always stock in vio files the first node (state) of a proof

\item {} 
\sphinxAtStartPar
STM: not delegate proofs that contain Vernac(Module|Require|Import), \#4530

\item {} 
\sphinxAtStartPar
Don't fail fatally if PATH is not set.

\item {} 
\sphinxAtStartPar
\#4537: Coq 8.5 is slower in typeclass resolution.

\item {} 
\sphinxAtStartPar
\#4522: Incorrect "Warning..." on windows.

\item {} 
\sphinxAtStartPar
\#4373: coqdep does not know about .vio files.

\item {} 
\sphinxAtStartPar
\#3826: "Incompatible module types" is uninformative.

\item {} 
\sphinxAtStartPar
\#4495: Failed assertion in metasyntax.ml.

\item {} 
\sphinxAtStartPar
\#4511: evar tactic can create non\sphinxhyphen{}typed evars.

\item {} 
\sphinxAtStartPar
\#4503: mixing universe polymorphic and monomorphic variables and definitions in sections is unsupported.

\item {} 
\sphinxAtStartPar
\#4519: oops, global shadowed local universe level bindings.

\item {} 
\sphinxAtStartPar
\#4506: Anomaly: File "pretyping/indrec.ml", line 169, characters 14\sphinxhyphen{}20: Assertion failed.

\item {} 
\sphinxAtStartPar
\#4548: CoqIDE crashes when going back one command

\end{itemize}


\paragraph{Details of changes in 8.5pl2}
\label{\detokenize{changes:details-of-changes-in-8-5pl2}}
\sphinxAtStartPar
Critical bugfix
\begin{itemize}
\item {} 
\sphinxAtStartPar
Checksums of .vo files dependencies were not correctly checked.

\item {} 
\sphinxAtStartPar
Unicode\sphinxhyphen{}to\sphinxhyphen{}ASCII translation was not injective, leading in a soundness bug in
the native compiler.

\end{itemize}

\sphinxAtStartPar
Other bugfixes
\begin{itemize}
\item {} 
\sphinxAtStartPar
\#4097: more efficient occur\sphinxhyphen{}check in presence of primitive projections

\item {} 
\sphinxAtStartPar
\#4398: type\_scope used consistently in "match goal".

\item {} 
\sphinxAtStartPar
\#4450: eauto does not work with polymorphic lemmas

\item {} 
\sphinxAtStartPar
\#4677: fix alpha\sphinxhyphen{}conversion in notations needing eta\sphinxhyphen{}expansion.

\item {} 
\sphinxAtStartPar
Fully preserve initial order of hypotheses in "Regular Subst Tactic" mode.

\item {} 
\sphinxAtStartPar
\#4644: a regression in unification.

\item {} 
\sphinxAtStartPar
\#4725: Function (Error: Conversion test raised an anomaly) and Program
(Error: Cannot infer this placeholder of type)

\item {} 
\sphinxAtStartPar
\#4747: Problem building Coq 8.5pl1 with OCaml 4.03.0: Fatal warnings

\item {} 
\sphinxAtStartPar
\#4752: CoqIDE crash on files not ended by ".v".

\item {} 
\sphinxAtStartPar
\#4777: printing inefficiency with implicit arguments

\item {} 
\sphinxAtStartPar
\#4818: "Admitted" fails due to undefined universe anomaly after calling
"destruct"

\item {} 
\sphinxAtStartPar
\#4823: remote counter: avoid thread race on sockets

\item {} 
\sphinxAtStartPar
\#4841: \sphinxhyphen{}verbose flag changed semantics in 8.5, is much harder to use

\item {} 
\sphinxAtStartPar
\#4851: {[}nsatz{]} cannot handle duplicated hypotheses

\item {} 
\sphinxAtStartPar
\#4858: Anomaly: Uncaught exception Failure("hd"). Please report. in variant
of nsatz

\item {} 
\sphinxAtStartPar
\#4880: {[}nsatz\_compute{]} generates invalid certificates if given redundant
hypotheses

\item {} 
\sphinxAtStartPar
\#4881: synchronizing "Declare Implicit Tactic" with backtrack.

\item {} 
\sphinxAtStartPar
\#4882: anomaly with Declare Implicit Tactic on hole of type with evars

\item {} 
\sphinxAtStartPar
Fix use of "Declare Implicit Tactic" in refine.
triggered by CoqIDE

\item {} 
\sphinxAtStartPar
\#4069, \#4718: congruence fails when universes are involved.

\end{itemize}

\sphinxAtStartPar
Universes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Disallow silently dropping universe instances applied to variables
(forward compatible)

\item {} 
\sphinxAtStartPar
Allow explicit universe instances on notations, when they can apply
to the head reference of their expansion.

\end{itemize}

\sphinxAtStartPar
Build infrastructure
\begin{itemize}
\item {} 
\sphinxAtStartPar
New update on how to find camlp5 binary and library at configure time.

\end{itemize}


\paragraph{Details of changes in 8.5pl3}
\label{\detokenize{changes:details-of-changes-in-8-5pl3}}
\sphinxAtStartPar
Critical bugfix
\begin{itemize}
\item {} 
\sphinxAtStartPar
\#4876: Guard checker incompleteness when using primitive projections

\end{itemize}

\sphinxAtStartPar
Other bugfixes
\begin{itemize}
\item {} 
\sphinxAtStartPar
\#4780: Induction with universe polymorphism on was creating ill\sphinxhyphen{}typed terms.

\item {} 
\sphinxAtStartPar
\#4673: regression in setoid\_rewrite, unfolding let\sphinxhyphen{}ins for type unification.

\item {} 
\sphinxAtStartPar
\#4754: Regression in setoid\_rewrite, allow postponed unification problems to remain.

\item {} 
\sphinxAtStartPar
\#4769: Anomaly with universe polymorphic schemes defined inside sections.

\item {} 
\sphinxAtStartPar
\#3886: Program: duplicate obligations of mutual fixpoints.

\item {} 
\sphinxAtStartPar
\#4994: Documentation typo.

\item {} 
\sphinxAtStartPar
\#5008: Use the "md5" command on OpenBSD.

\item {} 
\sphinxAtStartPar
\#5007: Do not assume the "TERM" environment variable is always set.

\item {} 
\sphinxAtStartPar
\#4606: Output a break before a list only if there was an empty line.

\item {} 
\sphinxAtStartPar
\#5001: metas not cleaned properly in clenv\_refine\_in.

\item {} 
\sphinxAtStartPar
\#2336: incorrect glob data for module symbols (bug \#2336).

\item {} 
\sphinxAtStartPar
\#4832: Remove extraneous dot in error message.

\item {} 
\sphinxAtStartPar
Anomaly in printing a unification error message.

\item {} 
\sphinxAtStartPar
\#4947: Options which take string arguments are not backwards compatible.

\item {} 
\sphinxAtStartPar
\#4156: micromega cache files are now hidden files.

\item {} 
\sphinxAtStartPar
\#4871: interrupting par:abstract kills coqtop.

\item {} 
\sphinxAtStartPar
\#5043: {[}Admitted{]} lemmas pick up section variables.

\item {} 
\sphinxAtStartPar
Fix name of internal refine ("simple refine").

\item {} 
\sphinxAtStartPar
\#5062: probably a typo in Strict Proofs mode.

\item {} 
\sphinxAtStartPar
\#5065: Anomaly: Not a proof by induction.

\item {} 
\sphinxAtStartPar
Restore native compiler optimizations, they were disabled since 8.5!

\item {} 
\sphinxAtStartPar
\#5077: failure on typing a fixpoint with evars in its type.

\item {} 
\sphinxAtStartPar
Fix recursive notation bug.

\item {} 
\sphinxAtStartPar
\#5095: non relevant too strict test in let\sphinxhyphen{}in abstraction.

\item {} 
\sphinxAtStartPar
Ensuring that the evar name is preserved by "rename".

\item {} 
\sphinxAtStartPar
\#4887: confusion between using and with in documentation of firstorder.

\item {} 
\sphinxAtStartPar
Bug in subst with let\sphinxhyphen{}ins.

\item {} 
\sphinxAtStartPar
\#4762: eauto weaker than auto.

\item {} 
\sphinxAtStartPar
Remove if\_then\_else (was buggy). Use tryif instead.

\item {} 
\sphinxAtStartPar
\#4970: confusion between special "\{" and non special "\{\{" in notations.

\item {} 
\sphinxAtStartPar
\#4529: primitive projections unfolding.

\item {} 
\sphinxAtStartPar
\#4416: Incorrect "Error: Incorrect number of goals".

\item {} 
\sphinxAtStartPar
\#4863: abstract in typeclass hint fails.

\item {} 
\sphinxAtStartPar
\#5123: unshelve can impact typeclass resolution

\item {} 
\sphinxAtStartPar
Fix a collision about the meta\sphinxhyphen{}variable ".." in recursive notations.

\item {} 
\sphinxAtStartPar
Fix printing of info\_auto.

\item {} 
\sphinxAtStartPar
\#3209: Not\_found due to an occur\sphinxhyphen{}check cycle.

\item {} 
\sphinxAtStartPar
\#5097: status of evars refined by "clear" in ltac: closed wrt evars.

\item {} 
\sphinxAtStartPar
\#5150: Missing dependency of the test\sphinxhyphen{}suite subsystems in prerequisite.

\item {} 
\sphinxAtStartPar
Fix a bug in error printing of unif constraints

\item {} 
\sphinxAtStartPar
\#3941: Do not stop propagation of signals when Coq is busy.

\item {} 
\sphinxAtStartPar
\#4822: Incorrect assertion in cbn.

\item {} 
\sphinxAtStartPar
\#3479 parsing of "\{" and "\}" when a keyword starts with "\{" or "\}".

\item {} 
\sphinxAtStartPar
\#5127: Memory corruption with the VM.

\item {} 
\sphinxAtStartPar
\#5102: bullets parsing broken by calls to parse\_entry.

\end{itemize}

\sphinxAtStartPar
Various documentation improvements


\subsubsection{Version 8.4}
\label{\detokenize{changes:version-8-4}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id947}}
\sphinxAtStartPar
Coq version 8.4 contains the result of three long\sphinxhyphen{}term projects: a new
modular library of arithmetic by Pierre Letouzey, a new proof engine by
Arnaud Spiwack and a new communication protocol for CoqIDE by Vincent
Gross.

\sphinxAtStartPar
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, ...

\sphinxAtStartPar
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\sphinxhyphen{}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.

\sphinxAtStartPar
Before version 8.4, CoqIDE was linked to Coq with the graphical
interface living in a separate thread. From version 8.4, CoqIDE is a
separate process communicating with Coq through a textual channel. This
allows for a more robust interfacing, the ability to interrupt 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\sphinxhyphen{}Marie Pédrot
contributed many various refinements of CoqIDE.

\sphinxAtStartPar
Coq 8.4 also comes with a bunch of various smaller\sphinxhyphen{}scale changes
and improvements regarding the different components of the system.

\sphinxAtStartPar
The underlying logic has been extended with η\sphinxhyphen{}conversion
thanks to Hugo Herbelin, Stéphane Glondu and Benjamin Grégoire. The
addition of η\sphinxhyphen{}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\sphinxhyphen{}theoretic model of CIC {[}\hyperlink{cite.zebibliography:id30}{LW11}{]}) is
applicable to the concrete implementation of Coq.

\sphinxAtStartPar
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 β\sphinxhyphen{}redexes that are blocked by the “match”
construction (blocked commutative cuts).

\sphinxAtStartPar
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.

\sphinxAtStartPar
Regarding the high\sphinxhyphen{}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.

\sphinxAtStartPar
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\sphinxhyphen{}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 {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.constr_eq}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{constr\_eq}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.is_evar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{is\_evar}}}}}, and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.has_evar}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{has\_evar}}}}}, to be used
when writing complex tactics. Enrico Tassi added support to fine\sphinxhyphen{}tuning
the behavior of {\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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
{\hyperref[\detokenize{proofs/writing-proofs/equality:coq:tacn.vm_compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{vm\_compute}}}}}. Bug fixes and miscellaneous improvements of the tactic
language came from Hugo Herbelin, Pierre Letouzey and Matthieu Sozeau.

\sphinxAtStartPar
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.

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

\sphinxAtStartPar
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\sphinxhyphen{}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\sphinxhyphen{}standing fact yet remaining unproved in
this library, namely that \(sin \frac{\pi}{2} =
1\).

\sphinxAtStartPar
Pierre Corbineau maintained the Mathematical Proof Language (C\sphinxhyphen{}zar).

\sphinxAtStartPar
Bruno Barras and Benjamin Grégoire maintained the call\sphinxhyphen{}by\sphinxhyphen{}value
reduction machines.

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

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

\sphinxAtStartPar
Julien Forest maintained the Function command.

\sphinxAtStartPar
Matthieu Sozeau maintained the setoid rewriting mechanism.

\sphinxAtStartPar
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.

\sphinxAtStartPar
Bruno Barras and Pierre Letouzey maintained the \sphinxcode{\sphinxupquote{coqchk}} checker.

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

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

\sphinxAtStartPar
Under the hood, the 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\sphinxhyphen{}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.

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

\sphinxAtStartPar
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\sphinxhyphen{}Marie Pédrot.

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

\sphinxAtStartPar
Many suggestions for improvements were motivated by feedback from users,
on either the bug tracker or the Coq\sphinxhyphen{}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}


\paragraph{Potential sources of incompatibilities}
\label{\detokenize{changes:id949}}
\sphinxAtStartPar
The main known incompatibilities between 8.3 and 8.4 are consequences
of the following changes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The reorganization of the library of numbers:

\sphinxAtStartPar
Several definitions have new names or are defined in modules of
different names, but a special care has been taken to have this
renaming transparent for the user thanks to compatibility notations.

\sphinxAtStartPar
However some definitions have changed, what might require some
adaptations. The most noticeable examples are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The "?=" notation which now bind to Pos.compare rather than former
Pcompare (now Pos.compare\_cont).

\item {} 
\sphinxAtStartPar
Changes in names may induce different automatically generated
names in proof scripts (e.g. when issuing "destruct Z\_le\_gt\_dec").

\item {} 
\sphinxAtStartPar
Z.add has a new definition, hence, applying "simpl" on subterms of
its body might give different results than before.

\item {} 
\sphinxAtStartPar
BigN.shiftl and BigN.shiftr have reversed arguments order, the
power function in BigN now takes two BigN.

\end{itemize}

\item {} 
\sphinxAtStartPar
Other changes in libraries:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The definition of functions over "vectors" (list of fixed length)
have changed.

\item {} 
\sphinxAtStartPar
TheoryList.v has been removed.

\end{itemize}

\item {} 
\sphinxAtStartPar
Slight changes in tactics:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Less unfolding of fixpoints when applying destruct or inversion on
a fixpoint hiding an inductive type (add an extra call to simpl to
preserve compatibility).

\item {} 
\sphinxAtStartPar
Less unexpected local definitions when applying "destruct"
(incompatibilities solvable by adapting name hypotheses).

\item {} 
\sphinxAtStartPar
Tactic "apply" might succeed more often, e.g. by now solving
pattern\sphinxhyphen{}matching of the form ?f x y = g(x,y) (compatibility
ensured by using "Unset Tactic Pattern Unification"), but also
because it supports (full) betaiota (using "simple apply" might
then help).

\item {} 
\sphinxAtStartPar
Tactic autorewrite does no longer instantiate pre\sphinxhyphen{}existing
existential variables.

\item {} 
\sphinxAtStartPar
Tactic "info" is now available only for auto, eauto and trivial.

\end{itemize}

\item {} 
\sphinxAtStartPar
Miscellaneous changes:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The command "Load" is now atomic for backtracking (use "Unset
Atomic Load" for compatibility).

\end{itemize}

\end{itemize}


\paragraph{Details of changes in 8.4beta}
\label{\detokenize{changes:details-of-changes-in-8-4beta}}
\sphinxAtStartPar
Logic
\begin{itemize}
\item {} 
\sphinxAtStartPar
Standard eta\sphinxhyphen{}conversion now supported (dependent product only).

\item {} 
\sphinxAtStartPar
Guard condition improvement: subterm property is propagated through beta\sphinxhyphen{}redex
blocked by pattern\sphinxhyphen{}matching, as in "(match v with C .. => fun x => u end) x";
this allows for instance to use "rewrite ... in ..." without breaking
the guard condition.

\end{itemize}

\sphinxAtStartPar
Specification language and notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
Maximal implicit arguments can now be set locally by \{ \}. The registration
traverses fixpoints and lambdas. Because there is conversion in types,
maximal implicit arguments are not taken into account in partial
applications (use eta expanded form with explicit \{ \} instead).

\item {} 
\sphinxAtStartPar
Added support for recursive notations with binders (allows for instance
to write "exists x y z, P").

\item {} 
\sphinxAtStartPar
Structure/Record printing can be disable by "Unset Printing Records".
In addition, it can be controlled on type by type basis using
"Add Printing Record" or "Add Printing Constructor".

\item {} 
\sphinxAtStartPar
Pattern\sphinxhyphen{}matching compilation algorithm: in "match x, y with ... end",
possible dependencies of x (or of the indices of its type) in the type
of y are now taken into account.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New proof engine.

\item {} 
\sphinxAtStartPar
Scripts can now be structured thanks to bullets \sphinxhyphen{} * + and to subgoal
delimitation via \{ \}. Note: for use with Proof General, a cvs version of
Proof General no older than mid\sphinxhyphen{}July 2011 is currently required.

\item {} 
\sphinxAtStartPar
Support for tactical "info" is suspended.

\item {} 
\sphinxAtStartPar
Support for command "Show Script" is suspended.

\item {} 
\sphinxAtStartPar
New tactics constr\_eq, is\_evar and has\_evar for use in Ltac (DOC TODO).

\item {} 
\sphinxAtStartPar
Removed the two\sphinxhyphen{}argument variant of "decide equality".

\item {} 
\sphinxAtStartPar
New experimental tactical "timeout <n> <tac>". Since <n> is a time
in second for the moment, this feature should rather be avoided
in scripts meant to be machine\sphinxhyphen{}independent.

\item {} 
\sphinxAtStartPar
Fix in "destruct": removal of unexpected local definitions in context might
result in some rare incompatibilities (solvable by adapting name hypotheses).

\item {} 
\sphinxAtStartPar
Introduction pattern "\_" made more robust.

\item {} 
\sphinxAtStartPar
Tactic (and Eval command) vm\_compute can now be interrupted via Ctrl\sphinxhyphen{}C.

\item {} 
\sphinxAtStartPar
Unification in "apply" supports unification of patterns of the form
?f x y = g(x,y) (compatibility ensured by using
"Unset Tactic Pattern Unification"). It also supports (full) betaiota.

\item {} 
\sphinxAtStartPar
Tactic autorewrite does no longer instantiate pre\sphinxhyphen{}existing
existential variables (theoretical source of possible incompatibilities).

\item {} 
\sphinxAtStartPar
Tactic "dependent rewrite" now supports equality in "sig".

\item {} 
\sphinxAtStartPar
Tactic omega now understands Zpred (wish \#1912) and can prove any goal
from a context containing an arithmetical contradiction (wish \#2236).

\item {} 
\sphinxAtStartPar
Using "auto with nocore" disables the use of the "core" database (wish \#2188).
This pseudo\sphinxhyphen{}database "nocore" can also be used with trivial and eauto.

\item {} 
\sphinxAtStartPar
Tactics "set", "destruct" and "induction" accepts incomplete terms and
use the goal to complete the pattern assuming it is non ambiguous.

\item {} 
\sphinxAtStartPar
When used on arguments with a dependent type, tactics such as
"destruct", "induction", "case", "elim", etc. now try to abstract
automatically the dependencies over the arguments of the types
(based on initial ideas from Chung\sphinxhyphen{}Kil Hur, extension to nested
dependencies suggested by Dan Grayson)

\item {} 
\sphinxAtStartPar
Tactic "injection" now failing on an equality showing no constructors while
it was formerly generalizing again the goal over the given equality.

\item {} 
\sphinxAtStartPar
In Ltac, the "context {[}...{]}" syntax has now a variant "appcontext {[}...{]}"
allowing to match partial applications in larger applications.

\item {} 
\sphinxAtStartPar
When applying destruct or inversion on a fixpoint hiding an inductive
type, recursive calls to the fixpoint now remain folded by default (rare
source of incompatibility generally solvable by adding a call to simpl).

\item {} 
\sphinxAtStartPar
In an ltac pattern containing a "match", a final "| \_ => \_" branch could be
used now instead of enumerating all remaining constructors. Moreover, the
pattern "match \_ with \_ => \_ end" now allows to match any "match". A "in"
annotation can also be added to restrict to a precise inductive type.

\item {} 
\sphinxAtStartPar
The behavior of "simpl" can be tuned using the "Arguments" vernacular.
In particular constants can be marked so that they are always/never unfolded
by "simpl", or unfolded only when a set of arguments evaluates to a
constructor. Last one can mark a constant so that it is unfolded only if the
simplified term does not expose a match in head position.

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
It is now mandatory to have a space (or tabulation or newline or end\sphinxhyphen{}of\sphinxhyphen{}file)
after a "." ending a sentence.

\item {} 
\sphinxAtStartPar
In SearchAbout, the {[} {]} delimiters are now optional.

\item {} 
\sphinxAtStartPar
New command "Add/Remove Search Blacklist <substring> ...":
a Search or SearchAbout or similar query will never mention lemmas
whose qualified names contain any of the declared substrings.
The default blacklisted substrings are \sphinxcode{\sphinxupquote{\_subproof}}, \sphinxcode{\sphinxupquote{Private\_}}.

\item {} 
\sphinxAtStartPar
When the output file of "Print Universes" ends in ".dot" or ".gv",
the universe graph is printed in the DOT language, and can be
processed by Graphviz tools.

\item {} 
\sphinxAtStartPar
New command "Print Sorted Universes".

\item {} 
\sphinxAtStartPar
The undocumented and obsolete option "Set/Unset Boxed Definitions" has
been removed, as well as syntaxes like "Boxed Fixpoint foo".

\item {} 
\sphinxAtStartPar
A new option "Set Default Timeout n / Unset Default Timeout".

\item {} 
\sphinxAtStartPar
Qed now uses information from the reduction tactics used in proof script
to avoid conversion at Qed time to go into a very long computation.

\item {} 
\sphinxAtStartPar
New command "Show Goal ident" to display the statement of a goal, even
a closed one (available from Proof General).

\item {} 
\sphinxAtStartPar
Command "Proof" accept a new modifier "using" to force generalization
over a given list of section variables at section ending (DOC TODO).

\item {} 
\sphinxAtStartPar
New command "Arguments" generalizing "Implicit Arguments" and
"Arguments Scope" and that also allows to rename the parameters of a
definition and to tune the behavior of the tactic "simpl".

\end{itemize}

\sphinxAtStartPar
Module System
\begin{itemize}
\item {} 
\sphinxAtStartPar
During subtyping checks, an opaque constant in a module type could now
be implemented by anything of the right type, even if bodies differ.
Said otherwise, with respect to subtyping, an opaque constant behaves
just as a parameter. Coqchk was already implementing this, but not coqtop.

\item {} 
\sphinxAtStartPar
The inlining done during application of functors can now be controlled
more precisely, by the annotations (no inline) or (inline at level XX).
With the latter annotation, only functor parameters whose levels
are lower or equal than XX will be inlined.
The level of a parameter can be fixed by "Parameter Inline(30) foo".
When levels aren't given, the default value is 100. One can also use
the flag "Set Inline Level ..." to set a level (DOC TODO).

\item {} 
\sphinxAtStartPar
Print Assumptions should now handle correctly opaque modules (\#2168).

\item {} 
\sphinxAtStartPar
Print Module (Type) now tries to print more details, such as types and
bodies of the module elements. Note that Print Module Type could be
used on a module to display only its interface. The option
"Set Short Module Printing" could be used to switch back to the earlier
behavior were only field names were displayed.

\end{itemize}

\sphinxAtStartPar
Libraries
\begin{itemize}
\item {} 
\sphinxAtStartPar
Extension of the abstract part of Numbers, which now provide axiomatizations
and results about many more integer functions, such as pow, gcd, lcm, sqrt,
log2 and bitwise functions. These functions are implemented for nat, N, BigN,
Z, BigZ. See in particular file NPeano for new functions about nat.

\item {} 
\sphinxAtStartPar
The definition of types positive, N, Z is now in file BinNums.v

\item {} 
\sphinxAtStartPar
Major reorganization of ZArith. The initial file ZArith/BinInt.v now contains
an internal module Z implementing the Numbers interface for integers.
This module Z regroups:
\begin{itemize}
\item {} 
\sphinxAtStartPar
all functions over type Z : Z.add, Z.mul, ...

\item {} 
\sphinxAtStartPar
the minimal proofs of specifications for these functions : Z.add\_0\_l, ...

\item {} 
\sphinxAtStartPar
an instantiation of all derived properties proved generically in Numbers :
Z.add\_comm, Z.add\_assoc, ...

\end{itemize}

\sphinxAtStartPar
A large part of ZArith is now simply compatibility notations, for instance
Zplus\_comm is an alias for Z.add\_comm. The direct use of module Z is now
recommended instead of relying on these compatibility notations.

\item {} 
\sphinxAtStartPar
Similar major reorganization of NArith, via a module N in NArith/BinNat.v

\item {} 
\sphinxAtStartPar
Concerning the positive datatype, BinPos.v is now in a specific directory
PArith, and contains an internal submodule Pos. We regroup there functions
such as Pos.add Pos.mul etc as well as many results about them. These results
are here proved directly (no Number interface for strictly positive numbers).

\item {} 
\sphinxAtStartPar
Note that in spite of the compatibility layers, all these reorganizations
may induce some marginal incompatibilies in scripts. In particular:
\begin{itemize}
\item {} 
\sphinxAtStartPar
the "?=" notation for positive now refers to a binary function Pos.compare,
instead of the infamous ternary Pcompare (now Pos.compare\_cont).

\item {} 
\sphinxAtStartPar
some hypothesis names generated by the system may changed (typically for
a "destruct Z\_le\_gt\_dec") since naming is done after the short name of
the head predicate (here now "le" in module Z instead of "Zle", etc).

\item {} 
\sphinxAtStartPar
the internals of Z.add has changed, now relying of Z.pos\_sub.

\end{itemize}

\item {} 
\sphinxAtStartPar
Also note these new notations:
\begin{itemize}
\item {} 
\sphinxAtStartPar
"<?" "<=?" "=?" for boolean tests such as Z.ltb Z.leb Z.eqb.

\item {} 
\sphinxAtStartPar
"÷" for the alternative integer division Z.quot implementing the Truncate
convention (former ZOdiv), while the notation for the Coq usual division
Z.div implementing the Flooring convention remains "/". Their corresponding
modulo functions are Z.rem (no notations) for Z.quot and Z.modulo (infix
"mod" notation) for Z.div.

\end{itemize}

\item {} 
\sphinxAtStartPar
Lemmas about conversions between these datatypes are also organized
in modules, see for instance modules Z2Nat, N2Z, etc.

\item {} 
\sphinxAtStartPar
When creating BigN, the macro\sphinxhyphen{}generated part NMake\_gen is much smaller.
The generic part NMake has been reworked and improved. Some changes
may introduce incompatibilities. In particular, the order of the arguments
for BigN.shiftl and BigN.shiftr is now reversed: the number to shift now
comes first. By default, the power function now takes two BigN.

\item {} 
\sphinxAtStartPar
Creation of Vector, an independent library for lists indexed by their length.
Vectors' names override lists' one so you should not "Import" the library.
All old names changed: function names follow the ocaml ones and, for example,
Vcons becomes Vector.cons. You can get {[}..;..;..{]}\sphinxhyphen{}style notations by importing
Vector.VectorNotations.

\item {} 
\sphinxAtStartPar
Removal of TheoryList. Requiring List instead should work most of the time.

\item {} 
\sphinxAtStartPar
New syntax "rew Heq in H" and "rew <\sphinxhyphen{} Heq in H" for eq\_rect and
eq\_rect\_r (available by importing module EqNotations).

\item {} 
\sphinxAtStartPar
Wf.iter\_nat is now Peano.nat\_iter (with an implicit type argument).

\end{itemize}

\sphinxAtStartPar
Internal infrastructure
\begin{itemize}
\item {} 
\sphinxAtStartPar
Opaque proofs are now loaded lazily by default. This allows to be almost as
fast as \sphinxhyphen{}dont\sphinxhyphen{}load\sphinxhyphen{}proofs, while being safer (no creation of axioms) and
avoiding feature restrictions (Print and Print Assumptions work ok).

\item {} 
\sphinxAtStartPar
Revised hash\sphinxhyphen{}consing code allowing more sharing of memory

\item {} 
\sphinxAtStartPar
Experimental support added for camlp4 (the one provided alongside ocaml),
simply pass option \sphinxhyphen{}usecamlp4 to ./configure. By default camlp5 is used.

\item {} 
\sphinxAtStartPar
Revised build system: no more stages in Makefile thanks to some recursive
aspect of recent gnu make, use of vo.itarget files containing .v to compile
for both make and ocamlbuild, etc.

\item {} 
\sphinxAtStartPar
Support of cross\sphinxhyphen{}compilation via mingw from unix toward Windows,
contact P. Letouzey for more informations.

\item {} 
\sphinxAtStartPar
New Makefile rules mli\sphinxhyphen{}doc to make html of mli in dev/doc/html and
full\sphinxhyphen{}stdlib to get a (huge) pdf reflecting the whole standard library.

\end{itemize}

\sphinxAtStartPar
Extraction
\begin{itemize}
\item {} 
\sphinxAtStartPar
By default, opaque terms are now truly considered opaque by extraction:
instead of accessing their body, they are now considered as axioms.
The previous behaviour can be reactivated via the option
"Set Extraction AccessOpaque".

\item {} 
\sphinxAtStartPar
The pretty\sphinxhyphen{}printer for Haskell now produces layout\sphinxhyphen{}independent code

\item {} 
\sphinxAtStartPar
A new command "Separate Extraction cst1 cst2 ..." that mixes a
minimal extracted environment a la "Recursive Extraction" and the
production of several files (one per coq source) a la "Extraction Library"
(DOC TODO).

\item {} 
\sphinxAtStartPar
New option "Set/Unset Extraction KeepSingleton" for preventing the
extraction to optimize singleton container types (DOC TODO).

\item {} 
\sphinxAtStartPar
The extraction now identifies and properly rejects a particular case of
universe polymorphism it cannot handle yet (the pair (I,I) being Prop).

\item {} 
\sphinxAtStartPar
Support of anonymous fields in record (\#2555).

\end{itemize}

\sphinxAtStartPar
CoqIDE
\begin{itemize}
\item {} 
\sphinxAtStartPar
CoqIDE now runs coqtop as separated process, making it more robust:
coqtop subprocess can be interrupted, or even killed and relaunched
(cf button "Restart Coq", ex\sphinxhyphen{}"Go to Start"). For allowing such
interrupts, the Windows version of coqide now requires Windows >= XP
SP1.

\item {} 
\sphinxAtStartPar
The communication between CoqIDE and coqtop is now done via a dialect
of XML (DOC TODO).

\item {} 
\sphinxAtStartPar
The backtrack engine of CoqIDE has been reworked, it now uses the
"Backtrack" command similarly to Proof General.

\item {} 
\sphinxAtStartPar
The CoqIDE parsing of sentences has be reworked and now supports
tactic delimitation via \{ \}.

\item {} 
\sphinxAtStartPar
CoqIDE now accepts the Abort command (wish \#2357).

\item {} 
\sphinxAtStartPar
CoqIDE can read coq\_makefile files as "project file" and use it to
set automatically options to send to coqtop.

\item {} 
\sphinxAtStartPar
Preference files have moved to \$XDG\_CONFIG\_HOME/coq and accelerators
are not stored as a list anymore.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Coq now searches directories specified in COQPATH, \$XDG\_DATA\_HOME/coq,
\$XDG\_DATA\_DIRS/coq, and user\sphinxhyphen{}contribs before the standard library.

\item {} 
\sphinxAtStartPar
Coq rc file has moved to \$XDG\_CONFIG\_HOME/coq.

\item {} 
\sphinxAtStartPar
Major changes to coq\_makefile:
\begin{itemize}
\item {} 
\sphinxAtStartPar
mli/mlpack/mllib taken into account, ml not preproccessed anymore, ml4 work;

\item {} 
\sphinxAtStartPar
mlihtml generates doc of mli, install\sphinxhyphen{}doc install the html doc in DOCDIR
with the same policy as vo in COQLIB;

\item {} 
\sphinxAtStartPar
More variables are given by coqtop \sphinxhyphen{}config, others are defined only if the
users doesn't have defined them elsewhere. Consequently, generated makefile
should work directly on any architecture;

\item {} 
\sphinxAtStartPar
Packagers can take advantage of \$(DSTROOT) introduction. Installation can
be made in \$XDG\_DATA\_HOME/coq;

\item {} 
\sphinxAtStartPar
\sphinxhyphen{}arg option allows to send option as argument to coqc.

\end{itemize}

\end{itemize}


\paragraph{Details of changes in 8.4beta2}
\label{\detokenize{changes:details-of-changes-in-8-4beta2}}
\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
Commands "Back" and "BackTo" are now handling the proof states. They may
perform some extra steps of backtrack to avoid states where the proof
state is unavailable (typically a closed proof).

\item {} 
\sphinxAtStartPar
The commands "Suspend" and "Resume" have been removed.

\item {} 
\sphinxAtStartPar
A basic Show Script has been reintroduced (no indentation).

\item {} 
\sphinxAtStartPar
New command "Set Parsing Explicit" for deactivating parsing (and printing)
of implicit arguments (useful for teaching).

\item {} 
\sphinxAtStartPar
New command "Grab Existential Variables" to transform the unresolved evars
at the end of a proof into goals.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Still no general "info" tactical, but new specific tactics info\_auto,
info\_eauto, info\_trivial which provides information on the proofs found
by auto/eauto/trivial. Display of these details could also be activated by
"Set Info Auto"/"Set Info Eauto"/"Set Info Trivial".

\item {} 
\sphinxAtStartPar
Details on everything tried by auto/eauto/trivial during a proof search
could be obtained by "debug auto", "debug eauto", "debug trivial" or by a
global "Set Debug Auto"/"Set Debug Eauto"/"Set Debug Trivial".

\item {} 
\sphinxAtStartPar
New command "r string" in Ltac debugger that interprets "idtac
string" in Ltac code as a breakpoint and jumps to its next use.

\item {} 
\sphinxAtStartPar
Tactics from the Dp plugin (simplify, ergo, yices, cvc3, z3, cvcl,
harvey, zenon, gwhy) have been removed, since Why2 has not been
maintained for the last few years. The Why3 plugin should be a suitable
replacement in most cases.

\end{itemize}

\sphinxAtStartPar
Libraries
\begin{itemize}
\item {} 
\sphinxAtStartPar
MSetRBT: a new implementation of MSets via Red\sphinxhyphen{}Black trees (initial
contribution by Andrew Appel).

\item {} 
\sphinxAtStartPar
MSetAVL: for maximal sharing with the new MSetRBT, the argument order
of Node has changed (this should be transparent to regular MSets users).

\end{itemize}

\sphinxAtStartPar
Module System
\begin{itemize}
\item {} 
\sphinxAtStartPar
The names of modules (and module types) are now in a fully separated
namespace from ordinary definitions: "Definition E:=0. Module E. End E."
is now accepted.

\end{itemize}

\sphinxAtStartPar
CoqIDE
\begin{itemize}
\item {} 
\sphinxAtStartPar
CoqIDE now supports the "Restart" command, and "Undo" (with a warning).
Better support for "Abort".

\end{itemize}


\paragraph{Details of changes in 8.4}
\label{\detokenize{changes:details-of-changes-in-8-4}}
\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
The "Reset" command is now supported again in files given to coqc or Load.

\item {} 
\sphinxAtStartPar
"Show Script" now indents again the displayed scripts. It can also work
correctly across Load'ed files if the option "Unset Atomic Load" is used.

\item {} 
\sphinxAtStartPar
"Open Scope" can now be given the delimiter (e.g. Z) instead of the full
scope name (e.g. Z\_scope).

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
Most compatibility notations of the standard library are now tagged as
(compat xyz), where xyz is a former Coq version, for instance "8.3".
These notations behave as (only parsing) notations, except that they may
triggers warnings (or errors) when used while Coq is not in a corresponding
\sphinxhyphen{}compat mode.

\item {} 
\sphinxAtStartPar
To activate these compatibility warnings, use "Set Verbose Compat Notations"
or the command\sphinxhyphen{}line flag \sphinxhyphen{}verbose\sphinxhyphen{}compat\sphinxhyphen{}notations.

\item {} 
\sphinxAtStartPar
For a strict mode without these compatibility notations, use
"Unset Compat Notations" or the command\sphinxhyphen{}line flag \sphinxhyphen{}no\sphinxhyphen{}compat\sphinxhyphen{}notations.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
An annotation "eqn:H" or "eqn:?" can be added to a "destruct"
or "induction" to make it generate equations in the spirit of "case\_eq".
The former syntax "\_eqn" is discontinued.

\item {} 
\sphinxAtStartPar
The name of the hypothesis introduced by tactic "remember" can be
set via the new syntax "remember t as x eqn:H" (wish \#2489).

\end{itemize}

\sphinxAtStartPar
Libraries
\begin{itemize}
\item {} 
\sphinxAtStartPar
Reals: changed definition of PI, no more axiom about sin(PI/2).

\item {} 
\sphinxAtStartPar
SetoidPermutation: a notion of permutation for lists modulo a setoid equality.

\item {} 
\sphinxAtStartPar
BigN: fixed the ocaml code doing the parsing/printing of big numbers.

\item {} 
\sphinxAtStartPar
List: a couple of lemmas added especially about no\sphinxhyphen{}duplication, partitions.

\item {} 
\sphinxAtStartPar
Init: Removal of the coercions between variants of sigma\sphinxhyphen{}types and
subset types (possible source of incompatibility).

\end{itemize}


\subsubsection{Version 8.3}
\label{\detokenize{changes:version-8-3}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id950}}
\sphinxAtStartPar
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.

\sphinxAtStartPar
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}\).

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

\sphinxAtStartPar
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\)\sphinxhyphen{}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{<+}} for nesting functor application that
provides a light notation for inheriting the properties of cascading
modules.

\sphinxAtStartPar
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.

\sphinxAtStartPar
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\sphinxhyphen{}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\sphinxhyphen{}Gianas grounded the support for Unicode on a more standard and
more robust basis.

\sphinxAtStartPar
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 Coq archive.
Vincent Gross provided support to CoqIDE. Jean\sphinxhyphen{}Marc Notin provided
support for benchmarking and archiving.

\sphinxAtStartPar
Many users helped by reporting problems, providing patches, suggesting
improvements or making useful comments, either on the bug tracker or on
the Coq\sphinxhyphen{}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, ...

\sphinxAtStartPar
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}


\paragraph{Details of changes}
\label{\detokenize{changes:details-of-changes}}
\sphinxAtStartPar
Rewriting tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Tactic "rewrite" now supports rewriting on ad hoc equalities such as eq\_true.

\item {} 
\sphinxAtStartPar
"Hint Rewrite" now checks that the lemma looks like an equation.

\item {} 
\sphinxAtStartPar
New tactic "etransitivity".

\item {} 
\sphinxAtStartPar
Support for heterogeneous equality (JMeq) in "injection" and "discriminate".

\item {} 
\sphinxAtStartPar
Tactic "subst" now supports heterogeneous equality and equality
proofs that are dependent (use "simple subst" for preserving compatibility).

\item {} 
\sphinxAtStartPar
Added support for Leibniz\sphinxhyphen{}rewriting of dependent hypotheses.

\item {} 
\sphinxAtStartPar
Renamed "Morphism" into "Proper" and "respect" into "proper\_prf"
(possible source of incompatibility). A partial fix is to define
"Notation Morphism R f := (Proper (R\%signature) f)."

\item {} 
\sphinxAtStartPar
New tactic variants "rewrite* by" and "autorewrite*" that rewrite
respectively the first and all matches whose side\sphinxhyphen{}conditions are
solved.

\item {} 
\sphinxAtStartPar
"Require Import Setoid" does not export all of "Morphisms" and
"RelationClasses" anymore (possible source of incompatibility, fixed
by importing "Morphisms" too).

\item {} 
\sphinxAtStartPar
Support added for using Chung\sphinxhyphen{}Kil Hur's Heq library for rewriting over
heterogeneous equality (courtesy of the library's author).

\item {} 
\sphinxAtStartPar
Tactic "replace" supports matching terms with holes.

\end{itemize}

\sphinxAtStartPar
Automation tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Tactic \sphinxcode{\sphinxupquote{intuition}} now preserves inner \sphinxcode{\sphinxupquote{iff}} and \sphinxcode{\sphinxupquote{not}} (exceptional
source of incompatibilities solvable by redefining \sphinxcode{\sphinxupquote{intuition}} as
\sphinxcode{\sphinxupquote{unfold iff, not in *; intuition}}, or, for iff only, by using
\sphinxcode{\sphinxupquote{Set Intuition Iff Unfolding}}.)

\item {} 
\sphinxAtStartPar
Tactic \sphinxcode{\sphinxupquote{tauto}} now proves classical tautologies as soon as classical logic
(i.e. library \sphinxcode{\sphinxupquote{Classical\_Prop}} or \sphinxcode{\sphinxupquote{Classical}}) is loaded.

\item {} 
\sphinxAtStartPar
Tactic \sphinxcode{\sphinxupquote{gappa}} has been removed from the Dp plugin.

\item {} 
\sphinxAtStartPar
Tactic \sphinxcode{\sphinxupquote{firstorder}} now supports the combination of its \sphinxcode{\sphinxupquote{using}} and
\sphinxcode{\sphinxupquote{with}} options.

\item {} 
\sphinxAtStartPar
New \sphinxcode{\sphinxupquote{Hint Resolve \sphinxhyphen{}>}} (or \sphinxcode{\sphinxupquote{<\sphinxhyphen{}}}) for declaring iff's as oriented
hints (wish \#2104).

\item {} 
\sphinxAtStartPar
An inductive type as argument of the \sphinxcode{\sphinxupquote{using}} option of \sphinxcode{\sphinxupquote{auto}} / \sphinxcode{\sphinxupquote{eauto}} / \sphinxcode{\sphinxupquote{firstorder}}
is interpreted as using the collection of its constructors.

\item {} 
\sphinxAtStartPar
New decision tactic "nsatz" to prove polynomial equations
by computation of Groebner bases.

\end{itemize}

\sphinxAtStartPar
Other tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Tactic "discriminate" now performs intros before trying to discriminate an
hypothesis of the goal (previously it applied intro only if the goal
had the form t1<>t2) (exceptional source of incompatibilities \sphinxhyphen{} former
behavior can be obtained by "Unset Discriminate Introduction").

\item {} 
\sphinxAtStartPar
Tactic "quote" now supports quotation of arbitrary terms (not just the
goal).

\item {} 
\sphinxAtStartPar
Tactic "idtac" now displays its "list" arguments.

\item {} 
\sphinxAtStartPar
New introduction patterns "*" for introducing the next block of dependent
variables and "**" for introducing all quantified variables and hypotheses.

\item {} 
\sphinxAtStartPar
Pattern Unification for existential variables activated in tactics and
new option "Unset Tactic Evars Pattern Unification" to deactivate it.

\item {} 
\sphinxAtStartPar
Resolution of canonical structure is now part of the tactic's unification
algorithm.

\item {} 
\sphinxAtStartPar
New tactic "decide lemma with hyp" for rewriting decidability lemmas
when one knows which side is true.

\item {} 
\sphinxAtStartPar
Improved support of dependent goals over objects in dependent types for
"destruct" (rare source of incompatibility that can be avoided by unsetting
option "Dependent Propositions Elimination").

\item {} 
\sphinxAtStartPar
Tactic "exists", "eexists", "destruct" and "edestruct" supports iteration
using comma\sphinxhyphen{}separated arguments.

\item {} 
\sphinxAtStartPar
Tactic names "case" and "elim" now support clauses "as" and "in" and become
then synonymous of "destruct" and "induction" respectively.

\item {} 
\sphinxAtStartPar
A new tactic name "exfalso" for the use of 'ex\sphinxhyphen{}falso quodlibet' principle.
This tactic is simply a shortcut for "elimtype False".

\item {} 
\sphinxAtStartPar
Made quantified hypotheses get the name they would have if introduced in
the context (possible but rare source of incompatibilities).

\item {} 
\sphinxAtStartPar
When applying a component of a conjunctive lemma, "apply in" (and
sequences of "apply in") now leave the side conditions of the lemmas
uniformly after the main goal (possible source of rare incompatibilities).

\item {} 
\sphinxAtStartPar
In "simpl c" and "change c with d", c can be a pattern.

\item {} 
\sphinxAtStartPar
Tactic "revert" now preserves let\sphinxhyphen{}in's making it the exact inverse of
"intro".

\item {} 
\sphinxAtStartPar
New tactics "clear dependent H" and "revert dependent H" that
clears (resp. reverts) H and all the hypotheses that depend on H.

\item {} 
\sphinxAtStartPar
Ltac's pattern\sphinxhyphen{}matching now supports matching metavariables that
depend on variables bound upwards in the pattern.

\end{itemize}

\sphinxAtStartPar
Tactic definitions
\begin{itemize}
\item {} 
\sphinxAtStartPar
Ltac definitions support Local option for non\sphinxhyphen{}export outside modules.

\item {} 
\sphinxAtStartPar
Support for parsing non\sphinxhyphen{}empty lists with separators in tactic notations.

\item {} 
\sphinxAtStartPar
New command "Locate Ltac" to get the full name of an Ltac definition.

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
Record syntax \sphinxcode{\sphinxupquote{\{|x=...; y=...|\}}} now works inside patterns too.

\item {} 
\sphinxAtStartPar
Abbreviations from non\sphinxhyphen{}imported module now invisible at printing time.

\item {} 
\sphinxAtStartPar
Abbreviations now use implicit arguments and arguments scopes for printing.

\item {} 
\sphinxAtStartPar
Abbreviations to pure names now strictly behave like the name they refer to
(make redirections of qualified names easier).

\item {} 
\sphinxAtStartPar
Abbreviations for applied constant now propagate the implicit arguments
and arguments scope of the underlying reference (possible source of
incompatibilities generally solvable by changing such abbreviations from
e.g. \sphinxcode{\sphinxupquote{Notation foo' := (foo x)}} to \sphinxcode{\sphinxupquote{Notation foo' y := (foo x (y:=y))}}).

\item {} 
\sphinxAtStartPar
The "where" clause now supports multiple notations per defined object.

\item {} 
\sphinxAtStartPar
Recursive notations automatically expand one step on the left for better
factorization; recursion notations inner separators now ensured being tokens.

\item {} 
\sphinxAtStartPar
Added "Reserved Infix" as a specific shortcut of the corresponding
"Reserved Notation".

\item {} 
\sphinxAtStartPar
Open/Close Scope command supports Global option in sections.

\end{itemize}

\sphinxAtStartPar
Specification language
\begin{itemize}
\item {} 
\sphinxAtStartPar
New support for local binders in the syntax of Record/Structure fields.

\item {} 
\sphinxAtStartPar
Fixpoint/CoFixpoint now support building part or all of bodies using tactics.

\item {} 
\sphinxAtStartPar
Binders given before ":" in lemmas and in definitions built by tactics are
now automatically introduced (possible source of incompatibility that can
be resolved by invoking "Unset Automatic Introduction").

\item {} 
\sphinxAtStartPar
New support for multiple implicit arguments signatures per reference.

\end{itemize}

\sphinxAtStartPar
Module system
\begin{itemize}
\item {} 
\sphinxAtStartPar
Include Type is now deprecated since Include now accepts both modules and
module types.

\item {} 
\sphinxAtStartPar
Declare ML Module supports Local option.

\item {} 
\sphinxAtStartPar
The sharing between non\sphinxhyphen{}logical object and the management of the
name\sphinxhyphen{}space has been improved by the new "Delta\sphinxhyphen{}equivalence" on
qualified name.

\item {} 
\sphinxAtStartPar
The include operator has been extended to high\sphinxhyphen{}order structures

\item {} 
\sphinxAtStartPar
Sequences of Include can be abbreviated via new syntax "<+".

\item {} 
\sphinxAtStartPar
A module (or module type) can be given several "<:" signatures.

\item {} 
\sphinxAtStartPar
Interactive proofs are now permitted in module type. Functors can hence
be declared as Module Type and be used later to type themselves.

\item {} 
\sphinxAtStartPar
A functor application can be prefixed by a "!" to make it ignore any
"Inline" annotation in the type of its argument(s) (for examples of
use of the new features, see libraries Structures and Numbers).

\item {} 
\sphinxAtStartPar
Coercions are now active only when modules are imported (use "Set Automatic
Coercions Import" to get the behavior of the previous versions of Coq).

\end{itemize}

\sphinxAtStartPar
Extraction
\begin{itemize}
\item {} 
\sphinxAtStartPar
When using (Recursive) Extraction Library, the filenames are directly the
Coq ones with new appropriate extensions : we do not force anymore
uncapital first letters for Ocaml and capital ones for Haskell.

\item {} 
\sphinxAtStartPar
The extraction now tries harder to avoid code transformations that can be
dangerous for the complexity. In particular many eta\sphinxhyphen{}expansions at the top
of functions body are now avoided, clever partial applications will likely
be preserved, let\sphinxhyphen{}ins are almost always kept, etc.

\item {} 
\sphinxAtStartPar
In the same spirit, auto\sphinxhyphen{}inlining is now disabled by default, except for
induction principles, since this feature was producing more frequently
weird code than clear gain. The previous behavior can be restored via
"Set Extraction AutoInline".

\item {} 
\sphinxAtStartPar
Unicode characters in identifiers are now transformed into ascii strings
that are legal in Ocaml and other languages.

\item {} 
\sphinxAtStartPar
Harsh support of module extraction to Haskell and Scheme: module hierarchy
is flattened, module abbreviations and functor applications are expanded,
module types and unapplied functors are discarded.

\item {} 
\sphinxAtStartPar
Less unsupported situations when extracting modules to Ocaml. In particular
module parameters might be alpha\sphinxhyphen{}renamed if a name clash is detected.

\item {} 
\sphinxAtStartPar
Extract Inductive is now possible toward non\sphinxhyphen{}inductive types (e.g. nat => int)

\item {} 
\sphinxAtStartPar
Extraction Implicit: this new experimental command allows to mark
some arguments of a function or constructor for removed during
extraction, even if these arguments don't fit the usual elimination
principles of extraction, for instance the length n of a vector.

\item {} 
\sphinxAtStartPar
Files ExtrOcaml*.v in plugins/extraction try to provide a library of common
extraction commands: mapping of basics types toward Ocaml's counterparts,
conversions from/to int and big\_int, or even complete mapping of nat,Z,N
to int or big\_int, or mapping of ascii to char and string to char list
(in this case recognition of ascii constants is hard\sphinxhyphen{}wired in the extraction).

\end{itemize}

\sphinxAtStartPar
Program
\begin{itemize}
\item {} 
\sphinxAtStartPar
Streamlined definitions using well\sphinxhyphen{}founded recursion and measures so
that they can work on any subset of the arguments directly (uses currying).

\item {} 
\sphinxAtStartPar
Try to automatically clear structural fixpoint prototypes in
obligations to avoid issues with opacity.

\item {} 
\sphinxAtStartPar
Use return type clause inference in pattern\sphinxhyphen{}matching as in the standard
typing algorithm.

\item {} 
\sphinxAtStartPar
Support {[}Local Obligation Tactic{]} and {[}Next Obligation with tactic{]}.

\item {} 
\sphinxAtStartPar
Use {[}Show Obligation Tactic{]} to print the current default tactic.

\item {} 
\sphinxAtStartPar
{[}fst{]} and {[}snd{]} have maximal implicit arguments in Program now (possible
source of incompatibility).

\end{itemize}

\sphinxAtStartPar
Type classes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Declaring axiomatic type class instances in Module Type should be now
done via new command "Declare Instance", while the syntax "Instance"
now always provides a concrete instance, both in and out of Module Type.

\item {} 
\sphinxAtStartPar
Use {[}Existing Class foo{]} to declare a preexisting object {[}foo{]} as a class.
{[}foo{]} can be an inductive type or a constant definition. No
projections or instances are defined.

\item {} 
\sphinxAtStartPar
Various bug fixes and improvements: support for defined fields,
anonymous instances, declarations giving terms, better handling of
sections and {[}Context{]}.

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
New command "Timeout <n> <command>." interprets a command and a timeout
interrupts the execution after <n> seconds.

\item {} 
\sphinxAtStartPar
New command "Compute <expr>." is a shortcut for "Eval vm\_compute in <expr>".

\item {} 
\sphinxAtStartPar
New command "Fail <command>." interprets a command and is successful iff
the command fails on an error (but not an anomaly). Handy for tests and
illustration of wrong commands.

\item {} 
\sphinxAtStartPar
Most commands referring to constant (e.g. Print or About) now support
referring to the constant by a notation string.

\item {} 
\sphinxAtStartPar
New option "Boolean Equality Schemes" to make generation of boolean
equality automatic for datatypes (together with option "Decidable
Equality Schemes", this replaces deprecated option "Equality Scheme").

\item {} 
\sphinxAtStartPar
Made support for automatic generation of case analysis schemes available
to user (governed by option "Set Case Analysis Schemes").

\item {} 
\sphinxAtStartPar
New command \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Global}\DUrole{notation-sup}{?}} Generalizable \DUrole{alternative}{\DUrole{alternative-block}{All}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{No}} \DUrole{alternative}{\DUrole{alternative-block}{Variable}\DUrole{alternative-separator}{​}\DUrole{alternative-block}{Variables}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/core/basic:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}} to
declare which identifiers are generalizable in `` \sphinxcode{\sphinxupquote{\{\} `}} and `` \sphinxcode{\sphinxupquote{() `}} binders.

\item {} 
\sphinxAtStartPar
New command "Print Opaque Dependencies" to display opaque constants in
addition to all variables, parameters or axioms a theorem or
definition relies on.

\item {} 
\sphinxAtStartPar
New command "Declare Reduction <id> := <conv\_expr>", allowing to write
later "Eval <id> in ...". This command accepts a Local variant.

\item {} 
\sphinxAtStartPar
Syntax of Implicit Type now supports more than one block of variables of
a given type.

\item {} 
\sphinxAtStartPar
Command "Canonical Structure" now warns when it has no effects.

\item {} 
\sphinxAtStartPar
Commands of the form "Set X" or "Unset X" now support "Local" and "Global"
prefixes.

\end{itemize}

\sphinxAtStartPar
Library
\begin{itemize}
\item {} 
\sphinxAtStartPar
Use "standard" Coq names for the properties of eq and identity
(e.g. refl\_equal is now eq\_refl). Support for compatibility is provided.

\item {} 
\sphinxAtStartPar
The function Compare\_dec.nat\_compare is now defined directly,
instead of relying on lt\_eq\_lt\_dec. The earlier version is still
available under the name nat\_compare\_alt.

\item {} 
\sphinxAtStartPar
Lemmas in library Relations and Reals have been homogenized a bit.

\item {} 
\sphinxAtStartPar
The implicit argument of Logic.eq is now maximally inserted, allowing
to simply write "eq" instead of "@eq \_" in morphism signatures.

\item {} 
\sphinxAtStartPar
Wrongly named lemmas (Zlt\_gt\_succ and Zlt\_succ\_gt) fixed (potential source
of incompatibilities)

\item {} 
\sphinxAtStartPar
List library:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Definitions of list, length and app are now in Init/Datatypes.
Support for compatibility is provided.

\item {} 
\sphinxAtStartPar
Definition of Permutation is now in Sorting/Permtation.v

\item {} 
\sphinxAtStartPar
Some other light revisions and extensions (possible source
of incompatibilities solvable by qualifying names accordingly).

\end{itemize}

\item {} 
\sphinxAtStartPar
In ListSet, set\_map has been fixed (source of incompatibilities if used).

\item {} 
\sphinxAtStartPar
Sorting library:
\begin{itemize}
\item {} 
\sphinxAtStartPar
new mergesort of worst\sphinxhyphen{}case complexity O(n*ln(n)) made available in
Mergesort.v;

\item {} 
\sphinxAtStartPar
former notion of permutation up to setoid from Permutation.v is
deprecated and moved to PermutSetoid.v;

\item {} 
\sphinxAtStartPar
heapsort from Heap.v of worst\sphinxhyphen{}case complexity O(n*n) is deprecated;

\item {} 
\sphinxAtStartPar
new file Sorted.v for some definitions of being sorted.

\end{itemize}

\item {} 
\sphinxAtStartPar
Structure library. This new library is meant to contain generic
structures such as types with equalities or orders, either
in Module version (for now) or Type Classes (still to do):
\begin{itemize}
\item {} 
\sphinxAtStartPar
DecidableType.v and OrderedType.v: initial notions for FSets/FMaps,
left for compatibility but considered as deprecated.

\item {} 
\sphinxAtStartPar
Equalities.v and Orders.v: evolutions of the previous files,
with fine\sphinxhyphen{}grain Module architecture, many variants, use of
Equivalence and other relevant Type Classes notions.

\item {} 
\sphinxAtStartPar
OrdersTac.v: a generic tactic for solving chains of (in)equalities
over variables. See \{Nat,N,Z,P\}OrderedType.v for concrete instances.

\item {} 
\sphinxAtStartPar
GenericMinMax.v: any ordered type can be equipped with min and max.
We derived here all the generic properties of these functions.

\end{itemize}

\item {} 
\sphinxAtStartPar
MSets library: an important evolution of the FSets library.
"MSets" stands for Modular (Finite) Sets, by contrast with a forthcoming
library of Class (Finite) Sets contributed by S. Lescuyer which will be
integrated with the next release of Coq. The main features of MSets are:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The use of Equivalence, Proper and other Type Classes features
easing the handling of setoid equalities.

\item {} 
\sphinxAtStartPar
The interfaces are now stated in iff\sphinxhyphen{}style. Old specifications
are now derived properties.

\item {} 
\sphinxAtStartPar
The compare functions are now pure, and return a "comparison" value.
Thanks to the CompSpec inductive type, reasoning on them remains easy.

\item {} 
\sphinxAtStartPar
Sets structures requiring invariants (i.e. sorted lists) are
built first as "Raw" sets (pure objects and separate proofs) and
attached with their proofs thanks to a generic functor. "Raw" sets
have now a proper interface and can be manipulated directly.

\end{itemize}

\sphinxAtStartPar
Note: No Maps yet in MSets. The FSets library is still provided
for compatibility, but will probably be considered as deprecated in the
next release of Coq.

\item {} 
\sphinxAtStartPar
Numbers library:
\begin{itemize}
\item {} 
\sphinxAtStartPar
The abstract layer (NatInt, Natural/Abstract, Integer/Abstract) has
been simplified and enhance thanks to new features of the module
system such as Include (see above). It has been extended to Euclidean
division (three flavors for integers: Trunc, Floor and Math).

\item {} 
\sphinxAtStartPar
The arbitrary\sphinxhyphen{}large efficient numbers (BigN, BigZ, BigQ) has also
been reworked. They benefit from the abstract layer improvements
(especially for div and mod). Note that some specifications have
slightly changed (compare, div, mod, shift\{r,l\}). Ring/Field should
work better (true recognition of constants).

\end{itemize}

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Option \sphinxhyphen{}R now supports binding Coq root read\sphinxhyphen{}only.

\item {} 
\sphinxAtStartPar
New coqtop/coqc option \sphinxhyphen{}beautify to reformat .v files (usable
e.g. to globally update notations).

\item {} 
\sphinxAtStartPar
New tool beautify\sphinxhyphen{}archive to beautify a full archive of developments.

\item {} 
\sphinxAtStartPar
New coqtop/coqc option \sphinxhyphen{}compat X.Y to simulate the general behavior
of previous versions of Coq (provides e.g. support for 8.2 compatibility).

\end{itemize}

\sphinxAtStartPar
Coqdoc
\begin{itemize}
\item {} 
\sphinxAtStartPar
List have been revamped.  List depth and scope is now determined by
an "offside" whitespace rule.

\item {} 
\sphinxAtStartPar
Text may be italicized by placing it in \_underscores\_.

\item {} 
\sphinxAtStartPar
The "\sphinxhyphen{}\sphinxhyphen{}index <string>" flag changes the filename of the index.

\item {} 
\sphinxAtStartPar
The "\sphinxhyphen{}\sphinxhyphen{}toc\sphinxhyphen{}depth <int>" flag limits the depth of headers which are
included in the table of contents.

\item {} 
\sphinxAtStartPar
The "\sphinxhyphen{}\sphinxhyphen{}lib\sphinxhyphen{}name <string>" flag prints "<string> Foo" instead of
"Library Foo" where library titles are called for.  The
"\sphinxhyphen{}\sphinxhyphen{}no\sphinxhyphen{}lib\sphinxhyphen{}name" flag eliminates the extra title.

\item {} 
\sphinxAtStartPar
New option "\sphinxhyphen{}\sphinxhyphen{}parse\sphinxhyphen{}comments" to allow parsing of regular \sphinxcode{\sphinxupquote{(* *)}}
comments.

\item {} 
\sphinxAtStartPar
New option "\sphinxhyphen{}\sphinxhyphen{}plain\sphinxhyphen{}comments" to disable interpretation inside comments.

\item {} 
\sphinxAtStartPar
New option "\sphinxhyphen{}\sphinxhyphen{}interpolate" to try and typeset identifiers in Coq escapings
using the available globalization information.

\item {} 
\sphinxAtStartPar
New option "\sphinxhyphen{}\sphinxhyphen{}external url root" to refer to external libraries.

\item {} 
\sphinxAtStartPar
Links to section variables and notations now supported.

\end{itemize}

\sphinxAtStartPar
Internal infrastructure
\begin{itemize}
\item {} 
\sphinxAtStartPar
To avoid confusion with the repository of user's contributions,
the subdirectory "contrib" has been renamed into "plugins".
On platforms supporting ocaml native dynlink, code located there
is built as loadable plugins for coqtop.

\item {} 
\sphinxAtStartPar
An experimental build mechanism via ocamlbuild is provided.
From the top of the archive, run ./configure as usual, and
then ./build. Feedback about this build mechanism is most welcome.
Compiling Coq on platforms such as Windows might be simpler
this way, but this remains to be tested.

\item {} 
\sphinxAtStartPar
The Makefile system has been simplified and factorized with
the ocamlbuild system. In particular "make" takes advantage
of .mllib files for building .cma/.cmxa. The .vo files to
compile are now listed in several vo.itarget files.

\end{itemize}


\subsubsection{Version 8.2}
\label{\detokenize{changes:version-8-2}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id951}}
\sphinxAtStartPar
Coq version 8.2 adds new features, new libraries and improves on many
various aspects.

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

\sphinxAtStartPar
Another major improvement of Coq 8.2 is the evolution of the arithmetic
libraries and of the tools associated with 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\sphinxhyphen{}theory concepts.

\sphinxAtStartPar
Frédéric Besson contributed a reflective tactic based on Krivine\sphinxhyphen{}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\sphinxhyphen{}Motzkin (for
linear systems in \(\mathbb{Q}\) and \(\mathbb{R}\)),
Fourier\sphinxhyphen{}Motzkin with cutting planes (for linear systems in
\(\mathbb{Z}\)) and sum\sphinxhyphen{}of\sphinxhyphen{}squares (for non\sphinxhyphen{}linear systems). Evgeny
Makarov made the platform generic over arbitrary ordered rings.

\sphinxAtStartPar
Arnaud Spiwack developed a library of 31\sphinxhyphen{}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\sphinxhyphen{}knowledge” so as to safely extend the
kernel\sphinxhyphen{}located bytecode\sphinxhyphen{}based efficient evaluation algorithm of Coq
version 8.1 to use 31\sphinxhyphen{}bits machine arithmetic for efficiently computing
with the library of integers he developed.

\sphinxAtStartPar
Beside the libraries, various improvements were contributed to provide a more
comfortable end\sphinxhyphen{}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\sphinxhyphen{}variables, more convenient notations...

\sphinxAtStartPar
É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.

\sphinxAtStartPar
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\sphinxhyphen{}Marc Notin provided help in debugging, general
maintenance and coqdoc support, Vincent Siles contributed extensions of
the Scheme command and of injection.

\sphinxAtStartPar
Bruno Barras implemented the \sphinxcode{\sphinxupquote{coqchk}} tool: this is a stand\sphinxhyphen{}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 Coq.

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

\sphinxAtStartPar
Julien Narboux contributed to 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 Coq and its
external interfaces. With Samuel Mimram, he also helped making 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\sphinxhyphen{}Microsoft Mathematical Components team, the Foundations group at
Radboud university in Nijmegen, reporters of bugs and participants to
the Coq\sphinxhyphen{}Club mailing list.

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


\paragraph{Details of changes}
\label{\detokenize{changes:id952}}
\sphinxAtStartPar
Language
\begin{itemize}
\item {} 
\sphinxAtStartPar
If a fixpoint is not written with an explicit \{ struct ... \}, then
all arguments are tried successively (from left to right) until one is
found that satisfies the structural decreasing condition.

\item {} 
\sphinxAtStartPar
New experimental typeclass system giving ad\sphinxhyphen{}hoc polymorphism and
overloading based on dependent records and implicit arguments.

\item {} 
\sphinxAtStartPar
New syntax "let 'pat := b in c" for let\sphinxhyphen{}binding using irrefutable patterns.

\item {} 
\sphinxAtStartPar
New syntax "forall \{A\}, T" for specifying maximally inserted implicit
arguments in terms.

\item {} 
\sphinxAtStartPar
Sort of Record/Structure, Inductive and CoInductive defaults to Type
if omitted.

\item {} 
\sphinxAtStartPar
(Co)Inductive types can be defined as records
(e.g. "CoInductive stream := \{ hd : nat; tl : stream \}.")

\item {} 
\sphinxAtStartPar
New syntax "Theorem id1:t1 ... with idn:tn" for proving mutually dependent
statements.

\item {} 
\sphinxAtStartPar
Support for sort\sphinxhyphen{}polymorphism on constants denoting inductive types.

\item {} 
\sphinxAtStartPar
Several evolutions of the module system (handling of module aliases,
functorial module types, an Include feature, etc).

\item {} 
\sphinxAtStartPar
Prop now a subtype of Set (predicative and impredicative forms).

\item {} 
\sphinxAtStartPar
Recursive inductive types in Prop with a single constructor of which
all arguments are in Prop is now considered to be a singleton
type. It consequently supports all eliminations to Prop, Set and Type.
As a consequence, Acc\_rect has now a more direct proof {[}possible source
of easily fixed incompatibility in case of manual definition of a recursor
in a recursive singleton inductive type{]}.

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added option Global to "Arguments Scope" for section surviving.

\item {} 
\sphinxAtStartPar
Added option "Unset Elimination Schemes" to deactivate the automatic
generation of elimination schemes.

\item {} 
\sphinxAtStartPar
Modification of the Scheme command so you can ask for the name to be
automatically computed (e.g. Scheme Induction for nat Sort Set).

\item {} 
\sphinxAtStartPar
New command "Combined Scheme" to build combined mutual induction
principles from existing mutual induction principles.

\item {} 
\sphinxAtStartPar
New command "Scheme Equality" to build a decidable (boolean) equality
for simple inductive datatypes and a decision property over this equality
(e.g.  Scheme Equality for nat).

\item {} 
\sphinxAtStartPar
Added option "Set Equality Scheme" to make automatic the declaration
of the boolean equality when possible.

\item {} 
\sphinxAtStartPar
Source of universe inconsistencies now printed when option
"Set Printing Universes" is activated.

\item {} 
\sphinxAtStartPar
New option "Set Printing Existential Instances" for making the display of
existential variable instances explicit.

\item {} 
\sphinxAtStartPar
Support for option "{[}id1 ... idn{]}", and "\sphinxhyphen{}{[}id1 ... idn{]}", for the
"compute"/"cbv" reduction strategy, respectively meaning reduce only, or
everything but, the constants id1 ... idn. "lazy" alone or followed by
"{[}id1 ... idn{]}", and "\sphinxhyphen{}{[}id1 ... idn{]}" also supported, meaning apply
all of beta\sphinxhyphen{}iota\sphinxhyphen{}zeta\sphinxhyphen{}delta, possibly restricting delta.

\item {} 
\sphinxAtStartPar
New command "Strategy" to control the expansion of constants during
conversion tests. It generalizes commands Opaque and Transparent by
introducing a range of levels. Lower levels are assigned to constants
that should be expanded first.

\item {} 
\sphinxAtStartPar
New options Global and Local to Opaque and Transparent.

\item {} 
\sphinxAtStartPar
New command "Print Assumptions" to display all variables, parameters
or axioms a theorem or definition relies on.

\item {} 
\sphinxAtStartPar
"Add Rec LoadPath" now provides references to libraries using partially
qualified names (this holds also for coqtop/coqc option \sphinxhyphen{}R).

\item {} 
\sphinxAtStartPar
SearchAbout supports negated search criteria, reference to logical objects
by their notation, and more generally search of subterms.

\item {} 
\sphinxAtStartPar
"Declare ML Module" now allows to import .cmxs files when Coq is
compiled in native code with a version of OCaml that supports native
Dynlink (>= 3.11).

\item {} 
\sphinxAtStartPar
Specific sort constraints on Record now taken into account.

\item {} 
\sphinxAtStartPar
"Print LoadPath" supports a path argument to filter the display.

\end{itemize}

\sphinxAtStartPar
Libraries
\begin{itemize}
\item {} 
\sphinxAtStartPar
Several parts of the libraries are now in Type, in particular FSets,
SetoidList, ListSet, Sorting, Zmisc. This may induce a few
incompatibilities. In case of trouble while fixing existing development,
it may help to simply declare Set as an alias for Type (see file
SetIsType).

\item {} 
\sphinxAtStartPar
New arithmetical library in theories/Numbers. It contains:
\begin{itemize}
\item {} 
\sphinxAtStartPar
an abstract modular development of natural and integer arithmetics
in Numbers/Natural/Abstract and Numbers/Integer/Abstract

\item {} 
\sphinxAtStartPar
an implementation of efficient computational bounded and unbounded
integers that can be mapped to processor native arithmetics.
See Numbers/Cyclic/Int31 for 31\sphinxhyphen{}bit integers and Numbers/Natural/BigN
for unbounded natural numbers and Numbers/Integer/BigZ for unbounded
integers.

\item {} 
\sphinxAtStartPar
some proofs that both older libraries Arith, ZArith and NArith and
newer BigN and BigZ implement the abstract modular development.
This allows in particular BigN and BigZ to already come with a
large database of basic lemmas and some generic tactics (ring),

\end{itemize}

\sphinxAtStartPar
This library has still an experimental status, as well as the
processor\sphinxhyphen{}acceleration mechanism, but both its abstract and its
concrete parts are already quite usable and could challenge the use
of nat, N and Z in actual developments. Moreover, an extension of
this framework to rational numbers is ongoing, and an efficient
Q structure is already provided (see Numbers/Rational/BigQ), but
this part is currently incomplete (no abstract layer and generic
lemmas).

\item {} 
\sphinxAtStartPar
Many changes in FSets/FMaps. In practice, compatibility with earlier
version should be fairly good, but some adaptations may be required.
\begin{itemize}
\item {} 
\sphinxAtStartPar
Interfaces of unordered ("weak") and ordered sets have been factorized
thanks to new features of Coq modules (in particular Include), see
FSetInterface. Same for maps. Hints in these interfaces have been
reworked (they are now placed in a "set" database).

\item {} 
\sphinxAtStartPar
To allow full subtyping between weak and ordered sets, a field
"eq\_dec" has been added to OrderedType. The old version of OrderedType
is now called MiniOrderedType and functor MOT\_to\_OT allow to
convert to the new version. The interfaces and implementations
of sets now contain also such a "eq\_dec" field.

\item {} 
\sphinxAtStartPar
FSetDecide, contributed by Aaron Bohannon, contains a decision
procedure allowing to solve basic set\sphinxhyphen{}related goals (for instance,
is a point in a particular set ?). See FSetProperties for examples.

\item {} 
\sphinxAtStartPar
Functors of properties have been improved, especially the ones about
maps, that now propose some induction principles. Some properties
of fold need less hypothesis.

\item {} 
\sphinxAtStartPar
More uniformity in implementations of sets and maps: they all use
implicit arguments, and no longer export unnecessary scopes (see
bug \#1347)

\item {} 
\sphinxAtStartPar
Internal parts of the implementations based on AVL have evolved a
lot. The main files FSetAVL and FMapAVL are now much more
lightweight now. In particular, minor changes in some functions
has allowed to fully separate the proofs of operational
correctness from the proofs of well\sphinxhyphen{}balancing: well\sphinxhyphen{}balancing is
critical for efficiency, but not anymore for proving that these
trees implement our interfaces, hence we have moved these proofs
into appendix files FSetFullAVL and FMapFullAVL. Moreover, a few
functions like union and compare have been modified in order to be
structural yet efficient. The appendix files also contains
alternative versions of these few functions, much closer to the
initial Ocaml code and written via the Function framework.

\end{itemize}

\item {} 
\sphinxAtStartPar
Library IntMap, subsumed by FSets/FMaps, has been removed from
Coq Standard Library and moved into a user contribution Cachan/IntMap

\item {} 
\sphinxAtStartPar
Better computational behavior of some constants (eq\_nat\_dec and
le\_lt\_dec more efficient, Z\_lt\_le\_dec and Positive\_as\_OT.compare
transparent, ...) (exceptional source of incompatibilities).

\item {} 
\sphinxAtStartPar
Boolean operators moved from module Bool to module Datatypes (may need
to rename qualified references in script and force notations || and \&\&
to be at levels 50 and 40 respectively).

\item {} 
\sphinxAtStartPar
The constructors xI and xO of type positive now have postfix notations
"\textasciitilde{}1" and "\textasciitilde{}0", allowing to write numbers in binary form easily, for instance
6 is 1\textasciitilde{}1\textasciitilde{}0 and 4*p is p\textasciitilde{}0\textasciitilde{}0 (see BinPos.v).

\item {} 
\sphinxAtStartPar
Improvements to NArith (Nminus, Nmin, Nmax), and to QArith (in particular
a better power function).

\item {} 
\sphinxAtStartPar
Changes in ZArith: several additional lemmas (used in theories/Numbers),
especially in Zdiv, Znumtheory, Zpower. Moreover, many results in
Zdiv have been generalized: the divisor may simply be non\sphinxhyphen{}null
instead of strictly positive (see lemmas with name ending by
"\_full"). An alternative file ZOdiv proposes a different behavior
(the one of Ocaml) when dividing by negative numbers.

\item {} 
\sphinxAtStartPar
Changes in Arith: EqNat and Wf\_nat now exported from Arith, some
constructions on nat that were outside Arith are now in (e.g. iter\_nat).

\item {} 
\sphinxAtStartPar
In SetoidList, eqlistA now expresses that two lists have similar elements
at the same position, while the predicate previously called eqlistA
is now equivlistA (this one only states that the lists contain the same
elements, nothing more).

\item {} 
\sphinxAtStartPar
Changes in Reals:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Most statement in "sigT" (including the
completeness axiom) are now in "sig" (in case of incompatibility,
use proj1\_sig instead of projT1, sig instead of sigT, etc).

\item {} 
\sphinxAtStartPar
More uniform naming scheme (identifiers in French moved to English,
consistent use of 0 \sphinxhyphen{}\sphinxhyphen{} zero \sphinxhyphen{}\sphinxhyphen{} instead of O \sphinxhyphen{}\sphinxhyphen{} letter O \sphinxhyphen{}\sphinxhyphen{}, etc).

\item {} 
\sphinxAtStartPar
Lemma on prod\_f\_SO is now on prod\_f\_R0.

\item {} 
\sphinxAtStartPar
Useless hypothesis of ln\_exists1 dropped.

\item {} 
\sphinxAtStartPar
New Rlogic.v states a few logical properties about R axioms.

\item {} 
\sphinxAtStartPar
RIneq.v extended and made cleaner.

\end{itemize}

\item {} 
\sphinxAtStartPar
Slight restructuration of the Logic library regarding choice and classical
logic. Addition of files providing intuitionistic axiomatizations of
descriptions: Epsilon.v, Description.v and IndefiniteDescription.v.

\item {} 
\sphinxAtStartPar
Definition of pred and minus made compatible with the structural
decreasing criterion for use in fixpoints.

\item {} 
\sphinxAtStartPar
Files Relations/Rstar.v and Relations/Newman.v moved out to the user
contribution repository (contribution CoC\_History). New lemmas about
transitive closure added and some bound variables renamed (exceptional
risk of incompatibilities).

\item {} 
\sphinxAtStartPar
Syntax for binders in terms (e.g. for "exists") supports anonymous names.

\end{itemize}

\sphinxAtStartPar
Notations, coercions, implicit arguments and type inference
\begin{itemize}
\item {} 
\sphinxAtStartPar
More automation in the inference of the return clause of dependent
pattern\sphinxhyphen{}matching problems.

\item {} 
\sphinxAtStartPar
Experimental allowance for omission of the clauses easily detectable as
impossible in pattern\sphinxhyphen{}matching problems.

\item {} 
\sphinxAtStartPar
Improved inference of implicit arguments.

\item {} 
\sphinxAtStartPar
New options "Set Maximal Implicit Insertion", "Set Reversible Pattern
Implicit", "Set Strongly Strict Implicit" and "Set Printing Implicit
Defensive" for controlling inference and use of implicit arguments.

\item {} 
\sphinxAtStartPar
New modifier in "Implicit Arguments" to force an implicit argument to
be maximally inserted.

\item {} 
\sphinxAtStartPar
New modifier of "Implicit Arguments" to enrich the set of implicit arguments.

\item {} 
\sphinxAtStartPar
New options Global and Local to "Implicit Arguments" for section
surviving or non export outside module.

\item {} 
\sphinxAtStartPar
Level "constr" moved from 9 to 8.

\item {} 
\sphinxAtStartPar
Structure/Record now printed as Record (unless option Printing All is set).

\item {} 
\sphinxAtStartPar
Support for parametric notations defining constants.

\item {} 
\sphinxAtStartPar
Insertion of coercions below product types refrains to unfold
constants (possible source of incompatibility).

\item {} 
\sphinxAtStartPar
New support for fix/cofix in notations.

\end{itemize}

\sphinxAtStartPar
Tactic Language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Second\sphinxhyphen{}order pattern\sphinxhyphen{}matching now working in Ltac "match" clauses
(syntax for second\sphinxhyphen{}order unification variable is "@?X").

\item {} 
\sphinxAtStartPar
Support for matching on let bindings in match context using syntax
"H := body" or "H := body : type".

\item {} 
\sphinxAtStartPar
Ltac accepts integer arguments (syntax is "ltac:nnn" for nnn an integer).

\item {} 
\sphinxAtStartPar
The general sequence tactical "expr\_0 ; {[} expr\_1 | ... | expr\_n {]}"
is extended so that at most one expr\_i may have the form "expr .."
or just "..". Also, n can be different from the number of subgoals
generated by expr\_0. In this case, the value of expr (or idtac in
case of just "..") is applied to the intermediate subgoals to make
the number of tactics equal to the number of subgoals.

\item {} 
\sphinxAtStartPar
A name used as the name of the parameter of a lemma (like f in
"apply f\_equal with (f:=t)") is now interpreted as a ltac variable
if such a variable exists (this is a possible source of
incompatibility and it can be fixed by renaming the variables of a
ltac function into names that do not clash with the lemmas
parameter names used in the tactic).

\item {} 
\sphinxAtStartPar
New syntax "Ltac tac ::= ..." to rebind a tactic to a new expression.

\item {} 
\sphinxAtStartPar
"let rec ... in ... " now supported for expressions without explicit
parameters; interpretation is lazy to the contrary of "let ... in ...";
hence, the "rec" keyword can be used to turn the argument of a
"let ... in ..." into a lazy one.

\item {} 
\sphinxAtStartPar
Patterns for hypotheses types in "match goal" are now interpreted in
type\_scope.

\item {} 
\sphinxAtStartPar
A bound variable whose name is not used elsewhere now serves as
metavariable in "match" and it gets instantiated by an identifier
(allow e.g. to extract the name of a statement like "exists x, P x").

\item {} 
\sphinxAtStartPar
New printing of Ltac call trace for better debugging.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New tactics "apply \sphinxhyphen{}> term", "apply <\sphinxhyphen{} term", "apply \sphinxhyphen{}> term in
ident", "apply <\sphinxhyphen{} term in ident" for applying equivalences (iff).

\item {} 
\sphinxAtStartPar
Slight improvement of the hnf and simpl tactics when applied on
expressions with explicit occurrences of match or fix.

\item {} 
\sphinxAtStartPar
New tactics "eapply in", "erewrite", "erewrite in".

\item {} 
\sphinxAtStartPar
New tactics "ediscriminate", "einjection", "esimplify\_eq".

\item {} 
\sphinxAtStartPar
Tactics "discriminate", "injection", "simplify\_eq" now support any
term as argument. Clause "with" is also supported.

\item {} 
\sphinxAtStartPar
Unfoldable references can be given by notation's string rather than by name
in unfold.

\item {} 
\sphinxAtStartPar
The "with" arguments are now typed using informations from the current goal:
allows support for coercions and more inference of implicit arguments.

\item {} 
\sphinxAtStartPar
Application of "f\_equal"\sphinxhyphen{}style lemmas works better.

\item {} 
\sphinxAtStartPar
Tactics elim, case, destruct and induction now support variants eelim,
ecase, edestruct and einduction.

\item {} 
\sphinxAtStartPar
Tactics destruct and induction now support the "with" option and the
"in" clause option. If the option "in" is used, an equality is added
to remember the term to which the induction or case analysis applied
(possible source of parsing incompatibilities when destruct or induction is
part of a let\sphinxhyphen{}in expression in Ltac; extra parentheses are then required).

\item {} 
\sphinxAtStartPar
New support for "as" clause in tactics "apply in" and "eapply in".

\item {} 
\sphinxAtStartPar
Some new intro patterns:
\begin{itemize}
\item {} 
\sphinxAtStartPar
intro pattern "?A" genererates a fresh name based on A.
Caveat about a slight loss of compatibility:
Some intro patterns don't need space between them. In particular
intros ?a?b used to be legal and equivalent to intros ? a ? b. Now it
is still legal but equivalent to intros ?a ?b.

\item {} 
\sphinxAtStartPar
intro pattern "(A \& ... \& Y \& Z)" synonym to "(A,....,(Y,Z)))))"
for right\sphinxhyphen{}associative constructs like /or exists.

\end{itemize}

\item {} 
\sphinxAtStartPar
Several syntax extensions concerning "rewrite":
\begin{itemize}
\item {} 
\sphinxAtStartPar
"rewrite A,B,C" can be used to rewrite A, then B, then C. These rewrites
occur only on the first subgoal: in particular, side\sphinxhyphen{}conditions of the
"rewrite A" are not concerned by the "rewrite B,C".

\item {} 
\sphinxAtStartPar
"rewrite A by tac" allows to apply tac on all side\sphinxhyphen{}conditions generated by
the "rewrite A".

\item {} 
\sphinxAtStartPar
"rewrite A at n" allows to select occurrences to rewrite: rewrite only
happen at the n\sphinxhyphen{}th exact occurrence of the first successful matching of
A in the goal.

\item {} 
\sphinxAtStartPar
"rewrite 3 A" or "rewrite 3!A" is equivalent to "rewrite A,A,A".

\item {} 
\sphinxAtStartPar
"rewrite !A" means rewriting A as long as possible (and at least once).

\item {} 
\sphinxAtStartPar
"rewrite 3?A" means rewriting A at most three times.

\item {} 
\sphinxAtStartPar
"rewrite ?A" means rewriting A as long as possible (possibly never).

\item {} 
\sphinxAtStartPar
many of the above extensions can be combined with each other.

\end{itemize}

\item {} 
\sphinxAtStartPar
Introduction patterns better respect the structure of context in presence of
missing or extra names in nested disjunction\sphinxhyphen{}conjunction patterns {[}possible
source of rare incompatibilities{]}.

\item {} 
\sphinxAtStartPar
New syntax "rename a into b, c into d" for "rename a into b; rename c into d"

\item {} 
\sphinxAtStartPar
New tactics "dependent induction/destruction H {[} generalizing id\_1 .. id\_n {]}"
to do induction\sphinxhyphen{}inversion on instantiated inductive families à la BasicElim.

\item {} 
\sphinxAtStartPar
Tactics "apply" and "apply in" now able to reason modulo unfolding of
constants (possible source of incompatibility in situations where apply
may fail, e.g. as argument of a try or a repeat and in a ltac function);
versions that do not unfold are renamed into "simple apply" and
"simple apply in" (usable for compatibility or for automation).

\item {} 
\sphinxAtStartPar
Tactics "apply" and "apply in" now able to traverse conjunctions and to
select the first matching lemma among the components of the conjunction;
tactic "apply" also able to apply lemmas of conclusion an empty type.

\item {} 
\sphinxAtStartPar
Tactic "apply" now supports application of several lemmas in a row.

\item {} 
\sphinxAtStartPar
Tactics "set" and "pose" can set functions using notation "(f x1..xn := c)".

\item {} 
\sphinxAtStartPar
New tactic "instantiate" (without argument).

\item {} 
\sphinxAtStartPar
Tactic firstorder "with" and "using" options have their meaning swapped for
consistency with auto/eauto (source of incompatibility).

\item {} 
\sphinxAtStartPar
Tactic "generalize" now supports "at" options to specify occurrences
and "as" options to name the quantified hypotheses.

\item {} 
\sphinxAtStartPar
New tactic "specialize H with a" or "specialize (H a)" allows to transform
in\sphinxhyphen{}place a universally\sphinxhyphen{}quantified hypothesis (H : forall x, T x) into its
instantiated form (H : T a). Nota: "specialize" was in fact there in earlier
versions of Coq, but was undocumented, and had a slightly different behavior.

\item {} 
\sphinxAtStartPar
New tactic "contradict H" can be used to solve any kind of goal as long as
the user can provide afterwards a proof of the negation of the hypothesis H.
If H is already a negation, say \textasciitilde{}T, then a proof of T is asked.
If the current goal is a negation, say \textasciitilde{}U, then U is saved in H afterwards,
hence this new tactic "contradict" extends earlier tactic "swap", which is
now obsolete.

\item {} 
\sphinxAtStartPar
Tactics f\_equal is now done in ML instead of Ltac: it now works on any
equality of functions, regardless of the arity of the function.

\item {} 
\sphinxAtStartPar
New options "before id", "at top", "at bottom" for tactics "move"/"intro".

\item {} 
\sphinxAtStartPar
Some more debug of reflexive omega (\sphinxcode{\sphinxupquote{romega}}), and internal clarifications.
Moreover, romega now has a variant \sphinxcode{\sphinxupquote{romega with *}} that can be also used
on non\sphinxhyphen{}Z goals (nat, N, positive) via a call to a translation tactic named
zify (its purpose is to Z\sphinxhyphen{}ify your goal...). This zify may also be used
independently of romega.

\item {} 
\sphinxAtStartPar
Tactic "remember" now supports an "in" clause to remember only selected
occurrences of a term.

\item {} 
\sphinxAtStartPar
Tactic "pose proof" supports name overriding in case of specialization of an
hypothesis.

\item {} 
\sphinxAtStartPar
Semi\sphinxhyphen{}decision tactic "jp" for first\sphinxhyphen{}order intuitionistic logic moved to user
contributions (subsumed by "firstorder").

\end{itemize}

\sphinxAtStartPar
Program
\begin{itemize}
\item {} 
\sphinxAtStartPar
Moved useful tactics in theories/Program and documented them.

\item {} 
\sphinxAtStartPar
Add Program.Basics which contains standard definitions for functional
programming (id, apply, flip...)

\item {} 
\sphinxAtStartPar
More robust obligation handling, dependent pattern\sphinxhyphen{}matching and
well\sphinxhyphen{}founded definitions.

\item {} 
\sphinxAtStartPar
New syntax " dest term as pat in term " for destructing objects using
an irrefutable pattern while keeping equalities (use this instead of
"let" in Programs).

\item {} 
\sphinxAtStartPar
Program CoFixpoint is accepted, Program Fixpoint uses the new way to infer
which argument decreases structurally.

\item {} 
\sphinxAtStartPar
Program Lemma, Axiom etc... now permit to have obligations in the statement
iff they can be automatically solved by the default tactic.

\item {} 
\sphinxAtStartPar
Renamed "Obligations Tactic" command to "Obligation Tactic".

\item {} 
\sphinxAtStartPar
New command "Preterm {[} of id {]}" to see the actual term fed to Coq for
debugging purposes.

\item {} 
\sphinxAtStartPar
New option "Transparent Obligations" to control the declaration of
obligations as transparent or opaque. All obligations are now transparent
by default, otherwise the system declares them opaque if possible.

\item {} 
\sphinxAtStartPar
Changed the notations "left" and "right" to "in\_left" and "in\_right" to hide
the proofs in standard disjunctions, to avoid breaking existing scripts when
importing Program. Also, put them in program\_scope.

\end{itemize}

\sphinxAtStartPar
Type Classes
\begin{itemize}
\item {} 
\sphinxAtStartPar
New "Class", "Instance" and "Program Instance" commands to define
classes and instances documented in the reference manual.

\item {} 
\sphinxAtStartPar
New binding construct " {[} Class\_1 param\_1 .. param\_n, Class\_2 ... {]} "
for binding type classes, usable everywhere.

\item {} 
\sphinxAtStartPar
New command " Print Classes " and " Print Instances some\_class " to
print tables for typeclasses.

\item {} 
\sphinxAtStartPar
New default eauto hint database "typeclass\_instances" used by the default
typeclass instance search tactic.

\item {} 
\sphinxAtStartPar
New theories directory "theories/Classes" for standard typeclasses
declarations. Module Classes.RelationClasses is a typeclass port of
Relation\_Definitions plus a generic development of algebra on
n\sphinxhyphen{}ary heterogeneous predicates.

\end{itemize}

\sphinxAtStartPar
Setoid rewriting
\begin{itemize}
\item {} 
\sphinxAtStartPar
Complete (and still experimental) rewrite of the tactic
based on typeclasses. The old interface and semantics are
almost entirely respected, except:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Import Setoid is now mandatory to be able to call setoid\_replace
and declare morphisms.

\item {} 
\sphinxAtStartPar
"\sphinxhyphen{}\sphinxhyphen{}>", "++>" and "==>" are now right associative notations
declared at level 55 in scope signature\_scope.
Their introduction may break existing scripts that defined
them as notations with different levels.

\item {} 
\sphinxAtStartPar
One needs to use {[}Typeclasses unfold {[}cst{]}{]} if {[}cst{]} is used
as an abbreviation hiding products in types of morphisms,
e.g. if ones redefines {[}relation{]} and declares morphisms
whose type mentions {[}relation{]}.

\item {} 
\sphinxAtStartPar
The {[}setoid\_rewrite{]}'s semantics change when rewriting with
a lemma: it can rewrite two different instantiations of the lemma
at once. Use {[}setoid\_rewrite H at 1{]} for (almost) the usual semantics.
{[}setoid\_rewrite{]} will also try to rewrite under binders now, and can
succeed on different terms than before. In particular, it will unify under
let\sphinxhyphen{}bound variables. When called through {[}rewrite{]}, the semantics are
unchanged though.

\item {} 
\sphinxAtStartPar
{[}Add Morphism term : id{]} has different semantics when used with
parametric morphism: it will try to find a relation on the parameters
too. The behavior has also changed with respect to default relations:
the most recently declared Setoid/Relation will be used, the documentation
explains how to customize this behavior.

\item {} 
\sphinxAtStartPar
Parametric Relation and Morphism are declared differently, using the
new {[}Add Parametric{]} commands, documented in the manual.

\item {} 
\sphinxAtStartPar
Setoid\_Theory is now an alias to Equivalence, scripts building objects
of type Setoid\_Theory need to unfold (or "red") the definitions
of Reflexive, Symmetric and Transitive in order to get the same goals
as before. Scripts which introduced variables explicitly will not break.

\item {} 
\sphinxAtStartPar
The order of subgoals when doing {[}setoid\_rewrite{]} with side\sphinxhyphen{}conditions
is always the same: first the new goal, then the conditions.

\end{itemize}

\item {} 
\sphinxAtStartPar
New standard library modules \sphinxcode{\sphinxupquote{Classes.Morphisms}} declares
standard morphisms on \sphinxcode{\sphinxupquote{refl}} / \sphinxcode{\sphinxupquote{sym}} / \sphinxcode{\sphinxupquote{trans}} relations.
\sphinxcode{\sphinxupquote{Classes.Morphisms\_Prop}} declares morphisms on propositional
connectives and \sphinxcode{\sphinxupquote{Classes.Morphisms\_Relations}} on generalized predicate
connectives. \sphinxcode{\sphinxupquote{Classes.Equivalence}} declares notations and tactics
related to equivalences and \sphinxcode{\sphinxupquote{Classes.SetoidTactics}} defines the
setoid\_replace tactics and some support for the \sphinxcode{\sphinxupquote{Add *}} interface,
notably the tactic applied automatically before each \sphinxcode{\sphinxupquote{Add Morphism}}
proof.

\item {} 
\sphinxAtStartPar
User\sphinxhyphen{}defined subrelations are supported, as well as higher\sphinxhyphen{}order morphisms
and rewriting under binders. The tactic is also extensible entirely in Ltac.
The documentation has been updated to cover these features.

\item {} 
\sphinxAtStartPar
{[}setoid\_rewrite{]} and {[}rewrite{]} now support the {[}at{]} modifier to select
occurrences to rewrite, and both use the {[}setoid\_rewrite{]} code, even when
rewriting with leibniz equality if occurrences are specified.

\end{itemize}

\sphinxAtStartPar
Extraction
\begin{itemize}
\item {} 
\sphinxAtStartPar
Improved behavior of the Caml extraction of modules: name clashes should
not happen anymore.

\item {} 
\sphinxAtStartPar
The command Extract Inductive has now a syntax for infix notations. This
allows in particular to map Coq lists and pairs onto OCaml ones:
\begin{itemize}
\item {} 
\sphinxAtStartPar
Extract Inductive list => list {[} "{[}{]}" "(::)" {]}.

\item {} 
\sphinxAtStartPar
Extract Inductive prod => "(*)" {[} "(,)" {]}.

\end{itemize}

\item {} 
\sphinxAtStartPar
In pattern matchings, a default pattern "| \_ \sphinxhyphen{}> ..." is now used whenever
possible if several branches are identical. For instance, functions
corresponding to decidability of equalities are now linear instead of
quadratic.

\item {} 
\sphinxAtStartPar
A new instruction Extraction Blacklist id1 .. idn allows to prevent filename
conflits with existing code, for instance when extracting module List
to Ocaml.

\end{itemize}

\sphinxAtStartPar
CoqIDE
\begin{itemize}
\item {} 
\sphinxAtStartPar
CoqIDE font defaults to monospace so as indentation to be meaningful.

\item {} 
\sphinxAtStartPar
CoqIDE supports nested goals and any other kind of declaration in the middle
of a proof.

\item {} 
\sphinxAtStartPar
Undoing non\sphinxhyphen{}tactic commands in CoqIDE works faster.

\item {} 
\sphinxAtStartPar
New CoqIDE menu for activating display of various implicit informations.

\item {} 
\sphinxAtStartPar
Added the possibility to choose the location of tabs in coqide:
(in Edit\sphinxhyphen{}>Preferences\sphinxhyphen{}>Misc)

\item {} 
\sphinxAtStartPar
New Open and Save As dialogs in CoqIDE which filter \sphinxcode{\sphinxupquote{*.v}} files.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
New stand\sphinxhyphen{}alone .vo files verifier "coqchk".

\item {} 
\sphinxAtStartPar
Extended \sphinxhyphen{}I coqtop/coqc option to specify a logical dir: "\sphinxhyphen{}I dir \sphinxhyphen{}as coqdir".

\item {} 
\sphinxAtStartPar
New coqtop/coqc option \sphinxhyphen{}exclude\sphinxhyphen{}dir to exclude subdirs for option \sphinxhyphen{}R.

\item {} 
\sphinxAtStartPar
The binary "parser" has been renamed to "coq\sphinxhyphen{}parser".

\item {} 
\sphinxAtStartPar
Improved coqdoc and dump of globalization information to give more
meta\sphinxhyphen{}information on identifiers. All categories of Coq definitions are
supported, which makes typesetting trivial in the generated documentation.
Support for hyperlinking and indexing developments in the tex output
has been implemented as well.

\end{itemize}

\sphinxAtStartPar
Miscellaneous
\begin{itemize}
\item {} 
\sphinxAtStartPar
Coq installation provides enough files so that Ocaml's extensions need not
the Coq sources to be compiled (this assumes O'Caml 3.10 and Camlp5).

\item {} 
\sphinxAtStartPar
New commands "Set Whelp Server" and "Set Whelp Getter" to customize the
Whelp search tool.

\item {} 
\sphinxAtStartPar
Syntax of "Test Printing Let ref" and "Test Printing If ref" changed into
"Test Printing Let for ref" and "Test Printing If for ref".

\item {} 
\sphinxAtStartPar
An overhauled build system (new Makefiles); see dev/doc/build\sphinxhyphen{}system.txt.

\item {} 
\sphinxAtStartPar
Add \sphinxhyphen{}browser option to configure script.

\item {} 
\sphinxAtStartPar
Build a shared library for the C part of Coq, and use it by default on
non\sphinxhyphen{}(Windows or MacOS) systems. Bytecode executables are now pure. The
behaviour is configurable with \sphinxhyphen{}coqrunbyteflags, \sphinxhyphen{}coqtoolsbyteflags and
\sphinxhyphen{}custom configure options.

\item {} 
\sphinxAtStartPar
Complexity tests can be skipped by setting the environment variable
COQTEST\_SKIPCOMPLEXITY.

\end{itemize}


\subsubsection{Version 8.1}
\label{\detokenize{changes:version-8-1}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id953}}
\sphinxAtStartPar
Coq version 8.1 adds various new functionalities.

\sphinxAtStartPar
Benjamin Grégoire implemented an alternative algorithm to check the
convertibility of terms in the 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.

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

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

\sphinxAtStartPar
Claudio Sacerdoti Coen added new features to the module system.

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

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

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

\sphinxAtStartPar
Hugo Herbelin implemented matching on disjunctive patterns.

\sphinxAtStartPar
New mechanisms made easier the communication between Coq and external
provers. Nicolas Ayache and Jean\sphinxhyphen{}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.

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

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

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

\sphinxAtStartPar
Pierre Corbineau extended his tactic for solving first\sphinxhyphen{}order statements.
He wrote a reflection\sphinxhyphen{}based intuitionistic tautology solver.

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

\sphinxAtStartPar
Jean\sphinxhyphen{}Marc Notin significantly contributed to the general maintenance of
the system. He also took care of \sphinxcode{\sphinxupquote{coqdoc}}.

\sphinxAtStartPar
Pierre Castéran contributed to the documentation of (co\sphinxhyphen{})inductive types
and suggested improvements to the libraries.

\sphinxAtStartPar
Pierre Corbineau implemented a declarative mathematical proof language,
usable in combination with the tactic\sphinxhyphen{}based style of proof.

\sphinxAtStartPar
Finally, many users suggested improvements of the system through the
Coq\sphinxhyphen{}Club mailing list and bug\sphinxhyphen{}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}


\paragraph{Details of changes in 8.1beta}
\label{\detokenize{changes:details-of-changes-in-8-1beta}}
\sphinxAtStartPar
Logic
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added sort\sphinxhyphen{}polymorphism on inductive families

\item {} 
\sphinxAtStartPar
Allowance for recursively non uniform parameters in inductive types

\end{itemize}

\sphinxAtStartPar
Syntax
\begin{itemize}
\item {} 
\sphinxAtStartPar
No more support for version 7 syntax and for translation to version 8 syntax.

\item {} 
\sphinxAtStartPar
In fixpoints, the \{ struct ... \} annotation is not mandatory any more when
only one of the arguments has an inductive type

\item {} 
\sphinxAtStartPar
Added disjunctive patterns in match\sphinxhyphen{}with patterns

\item {} 
\sphinxAtStartPar
Support for primitive interpretation of string literals

\item {} 
\sphinxAtStartPar
Extended support for Unicode ranges

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added "Print Ltac qualid" to print a user defined tactic.

\item {} 
\sphinxAtStartPar
Added "Print Rewrite HintDb" to print the content of a DB used by
autorewrite.

\item {} 
\sphinxAtStartPar
Added "Print Canonical Projections".

\item {} 
\sphinxAtStartPar
Added "Example" as synonym of "Definition".

\item {} 
\sphinxAtStartPar
Added "Proposition" and "Corollary" as extra synonyms of "Lemma".

\item {} 
\sphinxAtStartPar
New command "Whelp" to send requests to the Helm database of proofs
formalized in the Calculus of Inductive Constructions.

\item {} 
\sphinxAtStartPar
Command "functional induction" has been re\sphinxhyphen{}implemented from the new
"Function" command.

\end{itemize}

\sphinxAtStartPar
Ltac and tactic syntactic extensions
\begin{itemize}
\item {} 
\sphinxAtStartPar
New primitive "external" for communication with tool external to Coq

\item {} 
\sphinxAtStartPar
New semantics for "match t with": if a clause returns a
tactic, it is now applied to the current goal. If it fails, the next
clause or next matching subterm is tried (i.e. it behaves as "match
goal with" does). The keyword "lazymatch" can be used to delay the
evaluation of tactics occurring in matching clauses.

\item {} 
\sphinxAtStartPar
Hint base names can be parametric in auto and trivial.

\item {} 
\sphinxAtStartPar
Occurrence values can be parametric in unfold, pattern, etc.

\item {} 
\sphinxAtStartPar
Added entry constr\_may\_eval for tactic extensions.

\item {} 
\sphinxAtStartPar
Low\sphinxhyphen{}priority term printer made available in ML\sphinxhyphen{}written tactic extensions.

\item {} 
\sphinxAtStartPar
"Tactic Notation" extended to allow notations of tacticals.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New implementation and generalization of \sphinxcode{\sphinxupquote{setoid\_*}} (\sphinxcode{\sphinxupquote{setoid\_rewrite}},
\sphinxcode{\sphinxupquote{setoid\_symmetry}}, \sphinxcode{\sphinxupquote{setoid\_transitivity}}, \sphinxcode{\sphinxupquote{setoid\_reflexivity}} and \sphinxcode{\sphinxupquote{autorewite}}).
New syntax for declaring relations and morphisms (old syntax still working
with minor modifications, but deprecated).

\item {} 
\sphinxAtStartPar
New implementation (still experimental) of the ring tactic with a built\sphinxhyphen{}in
notion of coefficients and a better usage of setoids.

\item {} 
\sphinxAtStartPar
New conversion tactic "vm\_compute": evaluates the goal (or an hypothesis)
with a call\sphinxhyphen{}by\sphinxhyphen{}value strategy, using the compiled version of terms.

\item {} 
\sphinxAtStartPar
When rewriting H where H is not directly a Coq equality, search first H for
a registered setoid equality before starting to reduce in H. This is unlikely
to break any script. Should this happen nonetheless, one can insert manually
some "unfold ... in H" before rewriting.

\item {} 
\sphinxAtStartPar
Fixed various bugs about (setoid) rewrite ... in ... (in particular bug \#5941)

\item {} 
\sphinxAtStartPar
"rewrite ... in" now accepts a clause as place where to rewrite instead of
just a simple hypothesis name. For instance:
\sphinxcode{\sphinxupquote{rewrite H in H1,H2 |\sphinxhyphen{} *}} means \sphinxcode{\sphinxupquote{rewrite H in H1; rewrite H in H2; rewrite H}}
\sphinxcode{\sphinxupquote{rewrite H in * |\sphinxhyphen{}}}  will do try \sphinxcode{\sphinxupquote{rewrite H in Hi}} for all hypothesis Hi <> H.

\item {} 
\sphinxAtStartPar
Added "dependent rewrite term" and "dependent rewrite term in hyp".

\item {} 
\sphinxAtStartPar
Added "autorewrite with ... in hyp {[}using ...{]}".

\item {} 
\sphinxAtStartPar
Tactic "replace" now accepts a "by" tactic clause.

\item {} 
\sphinxAtStartPar
Added "clear \sphinxhyphen{} id" to clear all hypotheses except the ones depending in id.

\item {} 
\sphinxAtStartPar
The argument of Declare Left Step and Declare Right Step is now a term
(it used to be a reference).

\item {} 
\sphinxAtStartPar
Omega now handles arbitrary precision integers.

\item {} 
\sphinxAtStartPar
Several bug fixes in Reflexive Omega (romega).

\item {} 
\sphinxAtStartPar
Idtac can now be left implicit in a {[}...|...{]} construct: for instance,
{[} foo | | bar {]} stands for {[} foo | idtac | bar {]}.

\item {} 
\sphinxAtStartPar
Fixed a "fold" bug (non critical but possible source of incompatibilities).

\item {} 
\sphinxAtStartPar
Added classical\_left and classical\_right which transforms \sphinxcode{\sphinxupquote{|\sphinxhyphen{} A \textbackslash{}/ B}} into
\sphinxcode{\sphinxupquote{\textasciitilde{}B |\sphinxhyphen{} A}} and \sphinxcode{\sphinxupquote{\textasciitilde{}A |\sphinxhyphen{} B}} respectively.

\item {} 
\sphinxAtStartPar
Added command "Declare Implicit Tactic" to set up a default tactic to be
used to solve unresolved subterms of term arguments of tactics.

\item {} 
\sphinxAtStartPar
Better support for coercions to Sortclass in tactics expecting type
arguments.

\item {} 
\sphinxAtStartPar
Tactic "assert" now accepts "as" intro patterns and "by" tactic clauses.

\item {} 
\sphinxAtStartPar
New tactic "pose proof" that generalizes "assert (id:=p)" with intro patterns.

\item {} 
\sphinxAtStartPar
New introduction pattern "?" for letting Coq choose a name.

\item {} 
\sphinxAtStartPar
Introduction patterns now support side hypotheses (e.g. intros {[}|{]} on
"(nat \sphinxhyphen{}> nat) \sphinxhyphen{}> nat" works).

\item {} 
\sphinxAtStartPar
New introduction patterns "\sphinxhyphen{}>" and "<\sphinxhyphen{}" for immediate rewriting of
introduced hypotheses.

\item {} 
\sphinxAtStartPar
Introduction patterns coming after non trivial introduction patterns now
force full introduction of the first pattern (e.g. \sphinxcode{\sphinxupquote{intros {[}{[}|{]} p{]}}} on
\sphinxcode{\sphinxupquote{nat\sphinxhyphen{}>nat\sphinxhyphen{}>nat}} now behaves like \sphinxcode{\sphinxupquote{intros {[}{[}|?{]} p{]}}})

\item {} 
\sphinxAtStartPar
Added "eassumption".

\item {} 
\sphinxAtStartPar
Added option 'using lemmas' to auto, trivial and eauto.

\item {} 
\sphinxAtStartPar
Tactic "congruence" is now complete for its intended scope (ground
equalities and inequalities with constructors). Furthermore, it
tries to equates goal and hypotheses.

\item {} 
\sphinxAtStartPar
New tactic "rtauto" solves pure propositional logic and gives a
reflective version of the available proof.

\item {} 
\sphinxAtStartPar
Numbering of "pattern", "unfold", "simpl", ... occurrences in "match
with" made consistent with the printing of the return clause after
the term to match in the "match\sphinxhyphen{}with" construct (use "Set Printing All"
to see hidden occurrences).

\item {} 
\sphinxAtStartPar
Generalization of induction "induction x1...xn using scheme" where
scheme is an induction principle with complex predicates (like the
ones generated by function induction).

\item {} 
\sphinxAtStartPar
Some small Ltac tactics has been added to the standard library
(file Tactics.v):
\begin{itemize}
\item {} 
\sphinxAtStartPar
f\_equal : instead of using the different f\_equalX lemmas

\item {} 
\sphinxAtStartPar
case\_eq : a "case" without loss of information. An equality
stating the current situation is generated in every sub\sphinxhyphen{}cases.

\item {} 
\sphinxAtStartPar
swap : for a negated goal \textasciitilde{}B and a negated hypothesis H:\textasciitilde{}A,
swap H asks you to prove A from hypothesis B

\item {} 
\sphinxAtStartPar
revert : revert H is generalize H; clear H.

\end{itemize}

\end{itemize}

\sphinxAtStartPar
Extraction
\begin{itemize}
\item {} 
\sphinxAtStartPar
All type parts should now disappear instead of sometimes producing \_
(for instance in Map.empty).

\item {} 
\sphinxAtStartPar
Haskell extraction: types of functions are now printed, better
unsafeCoerce mechanism, both for hugs and ghc.

\item {} 
\sphinxAtStartPar
Scheme extraction improved, see \sphinxurl{http://www.pps.jussieu.fr/~letouzey/scheme}.

\item {} 
\sphinxAtStartPar
Many bug fixes.

\end{itemize}

\sphinxAtStartPar
Modules
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added "Locate Module qualid" to get the full path of a module.

\item {} 
\sphinxAtStartPar
Module/Declare Module syntax made more uniform.

\item {} 
\sphinxAtStartPar
Added syntactic sugar "Declare Module Export/Import" and
"Module Export/Import".

\item {} 
\sphinxAtStartPar
Added syntactic sugar "Module M(Export/Import X Y: T)" and
"Module Type M(Export/Import X Y: T)"
(only for interactive definitions)

\item {} 
\sphinxAtStartPar
Construct "with" generalized to module paths:
T with (Definition|Module) M1.M2....Mn.l := l'.

\end{itemize}

\sphinxAtStartPar
Notations
\begin{itemize}
\item {} 
\sphinxAtStartPar
Option "format" aware of recursive notations.

\item {} 
\sphinxAtStartPar
Added insertion of spaces by default in recursive notations w/o separators.

\item {} 
\sphinxAtStartPar
No more automatic printing box in case of user\sphinxhyphen{}provided printing "format".

\item {} 
\sphinxAtStartPar
New notation "exists! x:A, P" for unique existence.

\item {} 
\sphinxAtStartPar
Notations for specific numerals now compatible with generic notations of
numerals (e.g. "1" can be used to denote the unit of a group without
hiding 1\%nat)

\end{itemize}

\sphinxAtStartPar
Libraries
\begin{itemize}
\item {} 
\sphinxAtStartPar
New library on String and Ascii characters (contributed by L. Thery).

\item {} 
\sphinxAtStartPar
New library FSets+FMaps of finite sets and maps.

\item {} 
\sphinxAtStartPar
New library QArith on rational numbers.

\item {} 
\sphinxAtStartPar
Small extension of Zmin.V, new Zmax.v, new Zminmax.v.

\item {} 
\sphinxAtStartPar
Reworking and extension of the files on classical logic and
description principles (possible incompatibilities)

\item {} 
\sphinxAtStartPar
Few other improvements in ZArith potentially exceptionally breaking the
compatibility (useless hypothesys of Zgt\_square\_simpl and
Zlt\_square\_simpl removed; fixed names mentioning letter O instead of
digit 0; weaken premises in Z\_lt\_induction).

\item {} 
\sphinxAtStartPar
Restructuration of Eqdep\_dec.v and Eqdep.v: more lemmas in Type.

\item {} 
\sphinxAtStartPar
Znumtheory now contains a gcd function that can compute within Coq.

\item {} 
\sphinxAtStartPar
More lemmas stated on Type in Wf.v, removal of redundant Acc\_iter and
Acc\_iter2.

\item {} 
\sphinxAtStartPar
Change of the internal names of lemmas in OmegaLemmas.

\item {} 
\sphinxAtStartPar
Acc in Wf.v and clos\_refl\_trans in Relation\_Operators.v now rely on
the allowance for recursively non uniform parameters (possible
source of incompatibilities: explicit pattern\sphinxhyphen{}matching on these
types may require to remove the occurrence associated with their
recursively non uniform parameter).

\item {} 
\sphinxAtStartPar
Coq.List.In\_dec has been set transparent (this may exceptionally break
proof scripts, set it locally opaque for compatibility).

\item {} 
\sphinxAtStartPar
More on permutations of lists in List.v and Permutation.v.

\item {} 
\sphinxAtStartPar
List.v has been much expanded.

\item {} 
\sphinxAtStartPar
New file SetoidList.v now contains results about lists seen with
respect to a setoid equality.

\item {} 
\sphinxAtStartPar
Library NArith has been expanded, mostly with results coming from
Intmap (for instance a bitwise xor), plus also a bridge between N and
Bitvector.

\item {} 
\sphinxAtStartPar
Intmap has been reorganized. In particular its address type "addr" is
now N. User contributions known to use Intmap have been adapted
accordingly. If you're using this library please contact us.
A wrapper FMapIntMap now presents Intmap as a particular implementation
of FMaps. New developments are strongly encouraged to use either this
wrapper or any other implementations of FMap instead of using directly
this obsolete Intmap.

\end{itemize}

\sphinxAtStartPar
Tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
New semantics for coqtop options ("\sphinxhyphen{}batch" expects option "\sphinxhyphen{}top dir"
for loading vernac file that contains definitions).

\item {} 
\sphinxAtStartPar
Tool coq\_makefile now removes custom targets that are file names in
"make clean"

\item {} 
\sphinxAtStartPar
New environment variable COQREMOTEBROWSER to set the command invoked
to start the remote browser both in Coq and CoqIDE. Standard syntax:
"\%s" is the placeholder for the URL.

\end{itemize}


\paragraph{Details of changes in 8.1gamma}
\label{\detokenize{changes:details-of-changes-in-8-1gamma}}
\sphinxAtStartPar
Syntax
\begin{itemize}
\item {} 
\sphinxAtStartPar
changed parsing precedence of let/in and fun constructions of Ltac:
let x := t in e1; e2 is now parsed as let x := t in (e1;e2).

\end{itemize}

\sphinxAtStartPar
Language and commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added sort\sphinxhyphen{}polymorphism for definitions in Type (but finally abandoned).

\item {} 
\sphinxAtStartPar
Support for implicit arguments in the types of parameters in
(co\sphinxhyphen{})fixpoints and (co\sphinxhyphen{})inductive declarations.

\item {} 
\sphinxAtStartPar
Improved type inference: use as much of possible general information.
before applying irreversible unification heuristics (allow e.g. to
infer the predicate in "(exist \_ 0 (refl\_equal 0) : \{n:nat | n=0 \})").

\item {} 
\sphinxAtStartPar
Support for Miller\sphinxhyphen{}Pfenning's patterns unification in type synthesis
(e.g. can infer P such that P x y = phi(x,y)).

\item {} 
\sphinxAtStartPar
Support for "where" clause in cofixpoint definitions.

\item {} 
\sphinxAtStartPar
New option "Set Printing Universes" for making Type levels explicit.

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Improved implementation of the ring and field tactics. For compatibility
reasons, the previous tactics are renamed as legacy ring and legacy field,
but should be considered as deprecated.

\item {} 
\sphinxAtStartPar
New declarative mathematical proof language.

\item {} 
\sphinxAtStartPar
Support for argument lists of arbitrary length in Tactic Notation.

\item {} 
\sphinxAtStartPar
\sphinxcode{\sphinxupquote{rewrite ... in H}} now fails if \sphinxcode{\sphinxupquote{H}} is used either in an hypothesis
or in the goal.

\item {} 
\sphinxAtStartPar
The semantics of \sphinxcode{\sphinxupquote{rewrite ... in *}} has been slightly modified (see doc).

\item {} 
\sphinxAtStartPar
Support for \sphinxcode{\sphinxupquote{as}} clause in tactic injection.

\item {} 
\sphinxAtStartPar
New forward\sphinxhyphen{}reasoning tactic "apply in".

\item {} 
\sphinxAtStartPar
Ltac fresh operator now builds names from a concatenation of its arguments.

\item {} 
\sphinxAtStartPar
New ltac tactic "remember" to abstract over a subterm and keep an equality

\item {} 
\sphinxAtStartPar
Support for Miller\sphinxhyphen{}Pfenning's patterns unification in apply/rewrite/...
(may lead to few incompatibilities \sphinxhyphen{} generally now useless tactic calls).

\end{itemize}

\sphinxAtStartPar
Bug fixes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fix for notations involving basic "match" expressions.

\item {} 
\sphinxAtStartPar
Numerous other bugs solved (a few fixes may lead to incompatibilities).

\end{itemize}


\paragraph{Details of changes in 8.1}
\label{\detokenize{changes:details-of-changes-in-8-1}}
\sphinxAtStartPar
Bug fixes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Many bugs have been fixed (cf coq\sphinxhyphen{}bugs web page)

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
New tactics ring, ring\_simplify and new tactic field now able to manage
power to a positive integer constant. Tactic ring on Z and R, and
field on R manage power (may lead to incompatibilities with V8.1gamma).

\item {} 
\sphinxAtStartPar
Tactic field\_simplify now applicable in hypotheses.

\item {} 
\sphinxAtStartPar
New field\_simplify\_eq for simplifying field equations into ring equations.

\item {} 
\sphinxAtStartPar
Tactics ring, ring\_simplify, field, field\_simplify and field\_simplify\_eq
all able to apply user\sphinxhyphen{}given equations to rewrite monoms on the fly
(see documentation).

\end{itemize}

\sphinxAtStartPar
Libraries
\begin{itemize}
\item {} 
\sphinxAtStartPar
New file ConstructiveEpsilon.v defining an epsilon operator and
proving the axiom of choice constructively for a countable domain
and a decidable predicate.

\end{itemize}


\subsubsection{Version 8.0}
\label{\detokenize{changes:version-8-0}}

\paragraph{Summary of changes}
\label{\detokenize{changes:id954}}
\sphinxAtStartPar
Coq version 8 is a major revision of the Coq proof assistant. First, the
underlying logic is slightly different. The so\sphinxhyphen{}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.

\sphinxAtStartPar
Secondly, the concrete syntax of terms has been completely revised. The
main motivations were
\begin{itemize}
\item {} 
\sphinxAtStartPar
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 {} 
\sphinxAtStartPar
extensibility: some standard notations (e.g. “<” and “>”) were
incompatible with the previous syntax. Now all standard arithmetic
notations (=, +, *, /, <, <=, ... and more) are directly part of the
syntax.

\end{itemize}

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

\sphinxAtStartPar
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.

\sphinxAtStartPar
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 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.

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

\sphinxAtStartPar
Finally, the module system of Coq completes the picture of 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.

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

\sphinxAtStartPar
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 Coq is also their work
with contributions by Olivier Desmettre.

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

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

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

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

\sphinxAtStartPar
Claude Marché coordinated the edition of the Reference Manual for Coq
V8.0.

\sphinxAtStartPar
Pierre Letouzey and Jacek Chrząszcz respectively maintained the
extraction tool and module system of Coq.

\sphinxAtStartPar
Jean\sphinxhyphen{}Christophe Filliâtre, Pierre Letouzey, Hugo Herbelin and other
contributors from Sophia\sphinxhyphen{}Antipolis and Nijmegen participated in
extending the library.

\sphinxAtStartPar
Julien Narboux built a NSIS\sphinxhyphen{}based automatic Coq installation tool for
the Windows platform.

\sphinxAtStartPar
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}


\paragraph{Details of changes in 8.0beta old syntax}
\label{\detokenize{changes:details-of-changes-in-8-0beta-old-syntax}}
\sphinxAtStartPar
Logic
\begin{itemize}
\item {} 
\sphinxAtStartPar
Set now predicative by default

\item {} 
\sphinxAtStartPar
New option \sphinxhyphen{}impredicative\sphinxhyphen{}set to set Set impredicative

\item {} 
\sphinxAtStartPar
The standard library doesn't need impredicativity of Set and is
compatible with the classical axioms which contradict Set impredicativity

\end{itemize}

\sphinxAtStartPar
Syntax for arithmetic
\begin{itemize}
\item {} 
\sphinxAtStartPar
Notation "=" and "<>" in Z and R are no longer implicitly in Z or R
(with possible introduction of a coercion), use <Z>...=... or
<Z>...<>... instead

\item {} 
\sphinxAtStartPar
Locate applied to a simple string (e.g. "+") searches for all
notations containing this string

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Declare ML Module" now allows to import .cma files. This avoids to use a
bunch of "Declare ML Module" statements when using several ML files.

\item {} 
\sphinxAtStartPar
"Set Printing Width n" added, allows to change the size of width printing.

\item {} 
\sphinxAtStartPar
"Implicit Variables Type x,y:t" (new syntax: "Implicit Types x y:t")
assigns default types for binding variables.

\item {} 
\sphinxAtStartPar
Declarations of Hints and Notation now accept a "Local" flag not to
be exported outside the current file even if not in section

\item {} 
\sphinxAtStartPar
"Print Scopes" prints all notations

\item {} 
\sphinxAtStartPar
New command "About name" for light printing of type, implicit arguments, etc.

\item {} 
\sphinxAtStartPar
New command "Admitted" to declare incompletely proven statement as axioms

\item {} 
\sphinxAtStartPar
New keyword "Conjecture" to declare an axiom intended to be provable

\item {} 
\sphinxAtStartPar
SearchAbout can now search for lemmas referring to more than one constant
and on substrings of the name of the lemma

\item {} 
\sphinxAtStartPar
"Print Implicit" displays the implicit arguments of a constant

\item {} 
\sphinxAtStartPar
Locate now searches for all names having a given suffix

\item {} 
\sphinxAtStartPar
New command "Functional Scheme" for building an induction principle
from a function defined by case analysis and fix.

\end{itemize}

\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
new coqtop/coqc option \sphinxhyphen{}dont\sphinxhyphen{}load\sphinxhyphen{}proofs not to load opaque proofs in memory

\end{itemize}

\sphinxAtStartPar
Implicit arguments
\begin{itemize}
\item {} 
\sphinxAtStartPar
Inductive in sections declared with implicits now "discharged" with
implicits (like constants and variables)

\item {} 
\sphinxAtStartPar
Implicit Arguments flags are now synchronous with reset

\item {} 
\sphinxAtStartPar
New switch "Unset/Set Printing Implicits" (new syntax: "Unset/Set Printing
Implicit") to globally control printing of implicits

\end{itemize}

\sphinxAtStartPar
Grammar extensions
\begin{itemize}
\item {} 
\sphinxAtStartPar
Many newly supported UTF\sphinxhyphen{}8 encoded unicode blocks
\sphinxhyphen{} Greek letters (0380\sphinxhyphen{}03FF), Hebrew letters (U05D0\sphinxhyphen{}05EF), letter\sphinxhyphen{}like
symbols (2100\sphinxhyphen{}214F, that includes double N,Z,Q,R), prime
signs (from 2080\sphinxhyphen{}2089) and characters from many written languages
are valid in identifiers
\sphinxhyphen{} mathematical operators (2200\sphinxhyphen{}22FF), supplemental mathematical
operators (2A00\sphinxhyphen{}2AFF), miscellaneous technical (2300\sphinxhyphen{}23FF that
includes sqrt symbol), miscellaneous symbols (2600\sphinxhyphen{}26FF), arrows
(2190\sphinxhyphen{}21FF and 2900\sphinxhyphen{}297F), invisible mathematical operators (from
2080\sphinxhyphen{}2089), ... are valid symbols

\end{itemize}

\sphinxAtStartPar
Library
\begin{itemize}
\item {} 
\sphinxAtStartPar
New file about the factorial function in Arith

\item {} 
\sphinxAtStartPar
An additional elimination Acc\_iter for Acc, simpler than Acc\_rect.
This new elimination principle is used for definition well\_founded\_induction.

\item {} 
\sphinxAtStartPar
New library NArith on binary natural numbers

\item {} 
\sphinxAtStartPar
R is now of type Set

\item {} 
\sphinxAtStartPar
Restructuration in ZArith library
\begin{itemize}
\item {} 
\sphinxAtStartPar
"true\_sub" used in Zplus now a definition, not a local one (source
of incompatibilities in proof referring to true\_sub, may need extra Unfold)

\item {} 
\sphinxAtStartPar
Some lemmas about minus moved from fast\_integer to Arith/Minus.v
(le\_minus, lt\_mult\_left) (theoretical source of incompatibilities)

\item {} 
\sphinxAtStartPar
Several lemmas moved from auxiliary.v and zarith\_aux.v to
fast\_integer.v (theoretical source of incompatibilities)

\item {} 
\sphinxAtStartPar
Variables names of iff\_trans changed (source of incompatibilities)

\item {} 
\sphinxAtStartPar
ZArith lemmas named \sphinxcode{\sphinxupquote{OMEGA}} something or \sphinxcode{\sphinxupquote{fast\_}} something, and lemma \sphinxcode{\sphinxupquote{new\_var}}
are now out of ZArith (except \sphinxcode{\sphinxupquote{OMEGA2}})

\item {} 
\sphinxAtStartPar
Redundant ZArith lemmas have been renamed: for the following pairs,
use the second name (Zle\_Zmult\_right2, Zle\_mult\_simpl), (OMEGA2,
Zle\_0\_plus), (Zplus\_assoc\_l, Zplus\_assoc), (Zmult\_one, Zmult\_1\_n),
(Zmult\_assoc\_l, Zmult\_assoc), (Zmult\_minus\_distr, Zmult\_Zminus\_distr\_l)
(add\_un\_double\_moins\_un\_xO, is\_double\_moins\_un),
(Rlt\_monotony\_rev,Rlt\_monotony\_contra) (source of incompatibilities)

\end{itemize}

\item {} 
\sphinxAtStartPar
Few minor changes (no more implicit arguments in
Zmult\_Zminus\_distr\_l and Zmult\_Zminus\_distr\_r, lemmas moved from
Zcomplements to other files) (rare source of incompatibilities)

\item {} 
\sphinxAtStartPar
New lemmas provided by users added

\end{itemize}

\sphinxAtStartPar
Tactic language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Fail tactic now accepts a failure message

\item {} 
\sphinxAtStartPar
Idtac tactic now accepts a message

\item {} 
\sphinxAtStartPar
New primitive tactic "FreshId" (new syntax: "fresh") to generate new names

\item {} 
\sphinxAtStartPar
Debugger prints levels of calls

\end{itemize}

\sphinxAtStartPar
Tactics
\begin{itemize}
\item {} 
\sphinxAtStartPar
Replace can now replace proofs also

\item {} 
\sphinxAtStartPar
Fail levels are now decremented at "Match Context" blocks only and
if the right\sphinxhyphen{}hand\sphinxhyphen{}side of "Match term With" are tactics, these
tactics are never evaluated immediately and do not induce
backtracking (in contrast with "Match Context")

\item {} 
\sphinxAtStartPar
Quantified names now avoid global names of the current module (like
Intro names did) {[}source of rare incompatibilities: 2 changes in the set of
user contribs{]}

\item {} 
\sphinxAtStartPar
NewDestruct/NewInduction accepts intro patterns as introduction names

\item {} 
\sphinxAtStartPar
NewDestruct/NewInduction now work for non\sphinxhyphen{}inductive type using option "using"

\item {} 
\sphinxAtStartPar
A NewInduction naming bug for inductive types with functional
arguments (e.g. the accessibility predicate) has been fixed (source
of incompatibilities)

\item {} 
\sphinxAtStartPar
Symmetry now applies to hypotheses too

\item {} 
\sphinxAtStartPar
Inversion now accept option "as {[} ... {]}" to name the hypotheses

\item {} 
\sphinxAtStartPar
Contradiction now looks also for contradictory hypotheses stating \textasciitilde{}A and A
(source of incompatibility)

\item {} 
\sphinxAtStartPar
"Contradiction c" try to find an hypothesis in context which
contradicts the type of c

\item {} 
\sphinxAtStartPar
Ring applies to new library NArith (require file NArithRing)

\item {} 
\sphinxAtStartPar
Field now works on types in Set

\item {} 
\sphinxAtStartPar
Auto with reals now try to replace le by ge (Rge\_le is no longer an
immediate hint), resulting in shorter proofs

\item {} 
\sphinxAtStartPar
Instantiate now works in hyps (syntax : Instantiate in ...)

\item {} 
\sphinxAtStartPar
Some new tactics : EConstructor, ELeft, Eright, ESplit, EExists

\item {} 
\sphinxAtStartPar
New tactic "functional induction" to perform case analysis and
induction following the definition of a function.

\item {} 
\sphinxAtStartPar
Clear now fails when trying to remove a local definition used by
a constant appearing in the current goal

\end{itemize}

\sphinxAtStartPar
Extraction (See details in plugins/extraction/CHANGES)
\begin{itemize}
\item {} 
\sphinxAtStartPar
The old commands:     (Recursive) Extraction Module M.
are now:              (Recursive) Extraction Library M.
To use these commands, M should come from a library M.v

\item {} 
\sphinxAtStartPar
The other syntax Extraction \& Recursive Extraction now accept
module names as arguments.

\end{itemize}

\sphinxAtStartPar
Bugs
\begin{itemize}
\item {} 
\sphinxAtStartPar
see coq\sphinxhyphen{}bugs server for the complete list of fixed bugs

\end{itemize}

\sphinxAtStartPar
Miscellaneous
\begin{itemize}
\item {} 
\sphinxAtStartPar
Implicit parameters of inductive types definition now taken into
account for inferring other implicit arguments

\end{itemize}

\sphinxAtStartPar
Incompatibilities
\begin{itemize}
\item {} 
\sphinxAtStartPar
Persistence of true\_sub (4 incompatibilities in Coq user contributions)

\item {} 
\sphinxAtStartPar
Variable names of some constants changed for a better uniformity (2 changes
in Coq user contributions)

\item {} 
\sphinxAtStartPar
Naming of quantified names in goal now avoid global names (2 occurrences)

\item {} 
\sphinxAtStartPar
NewInduction naming for inductive types with functional arguments
(no incompatibility in Coq user contributions)

\item {} 
\sphinxAtStartPar
Contradiction now solve more goals (source of 2 incompatibilities)

\item {} 
\sphinxAtStartPar
Merge of eq and eqT may exceptionally result in subgoals now
solved automatically

\item {} 
\sphinxAtStartPar
Redundant pairs of ZArith lemmas may have different names: it may
cause "Apply/Rewrite with" to fail if using the first name of a pair
of redundant lemmas (this is solved by renaming the variables bound by
"with"; 3 incompatibilities in Coq user contribs)

\item {} 
\sphinxAtStartPar
ML programs referring to constants from fast\_integer.v must use
"Coqlib.gen\_constant\_modules Coqlib.zarith\_base\_modules" instead

\end{itemize}


\paragraph{Details of changes in 8.0beta new syntax}
\label{\detokenize{changes:details-of-changes-in-8-0beta-new-syntax}}
\sphinxAtStartPar
New concrete syntax
\begin{itemize}
\item {} 
\sphinxAtStartPar
A completely new syntax for terms

\item {} 
\sphinxAtStartPar
A more uniform syntax for tactics and the tactic language

\item {} 
\sphinxAtStartPar
A few syntactic changes for commands

\item {} 
\sphinxAtStartPar
A smart automatic translator translating V8.0 files in old syntax to
files valid for V8.0

\end{itemize}

\sphinxAtStartPar
Syntax extensions
\begin{itemize}
\item {} 
\sphinxAtStartPar
"Grammar" for terms disappears

\item {} 
\sphinxAtStartPar
"Grammar" for tactics becomes "Tactic Notation"

\item {} 
\sphinxAtStartPar
"Syntax" disappears

\item {} 
\sphinxAtStartPar
Introduction of a notion of notation scope allowing to use the
same notations in various contexts without using specific delimiters
(e.g the same expression "4<=3+x" is interpreted either in "nat",
"positive", "N" (previously "entier"), "Z", "R", depending on which
Notation scope is currently open) {[}see documentation for details{]}

\item {} 
\sphinxAtStartPar
Notation now requires a precedence and associativity
(default was to set precedence to 1 and associativity to none)

\end{itemize}

\sphinxAtStartPar
Revision of the standard library
\begin{itemize}
\item {} 
\sphinxAtStartPar
Many lemmas and definitions names have been made more uniform mostly
in Arith, NArith, ZArith and Reals (e.g : "times" \sphinxhyphen{}> "Pmult",
"times\_sym" \sphinxhyphen{}> "Pmult\_comm", "Zle\_Zmult\_pos\_right" \sphinxhyphen{}>
"Zmult\_le\_compat\_r", "SUPERIEUR" \sphinxhyphen{}> "Gt", "ZERO" \sphinxhyphen{}> "Z0")

\item {} 
\sphinxAtStartPar
Order and names of arguments of basic lemmas on nat, Z, positive and R
have been made uniform.

\item {} 
\sphinxAtStartPar
Notions of Coq initial state are declared with (strict) implicit arguments

\item {} 
\sphinxAtStartPar
eq merged with eqT: old eq disappear, new eq (written =) is old eqT
and new eqT is syntactic sugar for new eq (notation == is an alias
for = and is written as it, exceptional source of incompatibilities)

\item {} 
\sphinxAtStartPar
Similarly, ex, ex2, all, identity are merged with exT, exT2, allT, identityT

\item {} 
\sphinxAtStartPar
Arithmetical notations for nat, positive, N, Z, R, without needing
any backquote or double\sphinxhyphen{}backquotes delimiters.

\item {} 
\sphinxAtStartPar
In Lists: new concrete notations; argument of nil is now implicit

\item {} 
\sphinxAtStartPar
All changes in the library are taken in charge by the translator

\end{itemize}

\sphinxAtStartPar
Semantical changes during translation
\begin{itemize}
\item {} 
\sphinxAtStartPar
Recursive keyword set by default (and no longer needed) in Tactic Definition

\item {} 
\sphinxAtStartPar
Set Implicit Arguments is strict by default in new syntax

\item {} 
\sphinxAtStartPar
reductions in hypotheses of the form "... in H" now apply to the type
also if H is a local definition

\item {} 
\sphinxAtStartPar
etc

\end{itemize}

\sphinxAtStartPar
Gallina
\begin{itemize}
\item {} 
\sphinxAtStartPar
New syntax of the form "Inductive bool : Set := true, false : bool." for
enumerated types

\item {} 
\sphinxAtStartPar
Experimental syntax of the form p.(fst) for record projections
(activable with option "Set Printing Projections" which is
recognized by the translator)

\end{itemize}

\sphinxAtStartPar
Known problems of the automatic translation
\begin{itemize}
\item {} 
\sphinxAtStartPar
iso\sphinxhyphen{}latin\sphinxhyphen{}1 characters are no longer supported: move your files to
7\sphinxhyphen{}bits ASCII or unicode before translation (switch to unicode is
automatically done if a file is loaded and saved again by coqide)

\item {} 
\sphinxAtStartPar
Renaming in ZArith: incompatibilities in Coq user contribs due to
merging names INZ, from Reals, and inject\_nat.

\item {} 
\sphinxAtStartPar
Renaming and new lemmas in ZArith: may clash with names used by users

\item {} 
\sphinxAtStartPar
Restructuration of ZArith: replace requirement of specific modules
in ZArith by "Require Import ZArith\_base" or "Require Import ZArith"

\item {} 
\sphinxAtStartPar
Some implicit arguments must be made explicit before translation: typically
for "length nil", the implicit argument of length must be made explicit

\item {} 
\sphinxAtStartPar
Grammar rules, Infix notations and V7.4 Notations must be updated wrt the
new scheme for syntactic extensions (see translator documentation)

\item {} 
\sphinxAtStartPar
Unsafe for annotation Cases when constructors coercions are used or when
annotations are eta\sphinxhyphen{}reduced predicates

\end{itemize}


\paragraph{Details of changes in 8.0}
\label{\detokenize{changes:details-of-changes-in-8-0}}
\sphinxAtStartPar
Commands
\begin{itemize}
\item {} 
\sphinxAtStartPar
New option "Set Printing All" to deactivate all high\sphinxhyphen{}level forms of
printing (implicit arguments, coercions, destructing let,
if\sphinxhyphen{}then\sphinxhyphen{}else, notations, projections)

\item {} 
\sphinxAtStartPar
"Functional Scheme" and "Functional Induction" extended to polymorphic
types and dependent types

\item {} 
\sphinxAtStartPar
Notation now allows recursive patterns, hence recovering parts of the
functionalities of pre\sphinxhyphen{}V8 Grammar/Syntax commands

\item {} 
\sphinxAtStartPar
Command "Print." discontinued.

\item {} 
\sphinxAtStartPar
Redundant syntax "Implicit Arguments On/Off" discontinued

\end{itemize}

\sphinxAtStartPar
New syntax
\begin{itemize}
\item {} 
\sphinxAtStartPar
Semantics change of the if\sphinxhyphen{}then\sphinxhyphen{}else construction in new syntax:
"if c then t1 else t2" now stands for
"match c with c1 \_ ... \_ => t1 | c2 \_ ... \_ => t2 end"
with no dependency of t1 and t2 in the arguments of the constructors;
this may cause incompatibilities for files translated using coq 8.0beta

\end{itemize}

\sphinxAtStartPar
Notation scopes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Delimiting key \%bool for bool\_scope added

\item {} 
\sphinxAtStartPar
Import no more needed to activate argument scopes from a module

\end{itemize}

\sphinxAtStartPar
Tactics and the tactic Language
\begin{itemize}
\item {} 
\sphinxAtStartPar
Semantics of "assert" is now consistent with the reference manual

\item {} 
\sphinxAtStartPar
New tactics stepl and stepr for chaining transitivity steps

\item {} 
\sphinxAtStartPar
Tactic "replace ... with ... in" added

\item {} 
\sphinxAtStartPar
Intro patterns now supported in Ltac (parsed with prefix "ipattern:")

\end{itemize}

\sphinxAtStartPar
Executables and tools
\begin{itemize}
\item {} 
\sphinxAtStartPar
Added option \sphinxhyphen{}top to change the name of the toplevel module "Top"

\item {} 
\sphinxAtStartPar
Coqdoc updated to new syntax and now part of Coq sources

\item {} 
\sphinxAtStartPar
XML exportation tool now exports the structure of vernacular files
(cf chapter 13 in the reference manual)

\end{itemize}

\sphinxAtStartPar
User contributions
\begin{itemize}
\item {} 
\sphinxAtStartPar
User contributions have been updated to the new syntax

\end{itemize}

\sphinxAtStartPar
Bug fixes
\begin{itemize}
\item {} 
\sphinxAtStartPar
Many bugs have been fixed (cf coq\sphinxhyphen{}bugs web page)

\end{itemize}
\phantomsection\label{\detokenize{zebibliography:bibliography}}
\sphinxAtStartPar


\begin{sphinxthebibliography}{GimenezC}
\bibitem[AC19]{zebibliography:id55}
\sphinxAtStartPar
Andreas Abel and Thierry Coquand. Failure of Normalization in Impredicative Type Theory with Proof\sphinxhyphen{}Irrelevant Propositional Equality. Technical Report, Chalmers and Gothenburg University, 2019.
\bibitem[Bar81]{zebibliography:id3}
\sphinxAtStartPar
H.P. Barendregt. \sphinxstyleemphasis{The Lambda Calculus its Syntax and Semantics}. North\sphinxhyphen{}Holland, 1981.
\bibitem[BDenesGregoire11]{zebibliography:id53}
\sphinxAtStartPar
Mathieu Boespflug, Maxime Dénès, and Benjamin Grégoire. Full reduction at full throttle. In Jean\sphinxhyphen{}Pierre Jouannaud and Zhong Shao, editors, \sphinxstyleemphasis{Certified Programs and Proofs \sphinxhyphen{} First International Conference, CPP 2011, Kenting, Taiwan, December 7\sphinxhyphen{}9, 2011. Proceedings}, volume 7086 of Lecture Notes in Computer Science, 362–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\sphinxhyphen{}3\sphinxhyphen{}642\sphinxhyphen{}25379\sphinxhyphen{}9\_26}%
\begin{footnote}[967]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/978-3-642-25379-9\_26}
%
\end{footnote}.
\bibitem[Bou97]{zebibliography:id4}
\sphinxAtStartPar
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\sphinxhyphen{}Verlag, 1997.
\bibitem[CF07]{zebibliography:id56}
\sphinxAtStartPar
Sylvain Conchon and Jean\sphinxhyphen{}Christophe Filliâtre. A persistent union\sphinxhyphen{}find data structure. In \sphinxstyleemphasis{ACM SIGPLAN Workshop on ML}, 37–45. Freiburg, Germany, October 2007. ACM Press. URL: \sphinxurl{https://www.lri.fr/~filliatr/ftp/publis/puf-wml07.pdf}.
\bibitem[Coq89]{zebibliography:id9}
\sphinxAtStartPar
T. Coquand. Metamathematical investigations of a calculus of constructions. Technical Report RR\sphinxhyphen{}1088, INRIA, September 1989. URL: \sphinxurl{https://hal.inria.fr/inria-00075471}.
\bibitem[CH86a]{zebibliography:id8}
\sphinxAtStartPar
T. Coquand and Gérard Huet. Concepts mathematiques et informatiques formalises dans le calcul des constructions. Technical Report RR\sphinxhyphen{}0515, INRIA, April 1986. URL: \sphinxurl{https://hal.inria.fr/inria-00076039}.
\bibitem[CH86b]{zebibliography:id7}
\sphinxAtStartPar
T. Coquand and Gérard Huet. The calculus of constructions. Technical Report RR\sphinxhyphen{}0530, INRIA, May 1986. URL: \sphinxurl{https://hal.inria.fr/inria-00076024}.
\bibitem[Coq85]{zebibliography:id10}
\sphinxAtStartPar
Th. Coquand. \sphinxstyleemphasis{Une Théorie des Constructions}. PhD thesis, Université Paris 7, January 1985.
\bibitem[Coq86]{zebibliography:id11}
\sphinxAtStartPar
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:id12}
\sphinxAtStartPar
Th. Coquand. Pattern Matching with Dependent Types. In \sphinxstyleemphasis{Proceedings of the 1992 Workshop on Types for Proofs and Programs}. 1992.
\bibitem[CH85]{zebibliography:id6}
\sphinxAtStartPar
Thierry Coquand and Gérard Huet. Constructions: a higher order proof system for mechanizing mathematics. In \sphinxstyleemphasis{European Conference on Computer Algebra}, 151–184. Springer Berlin Heidelberg, 1985. URL: \sphinxurl{http://dx.doi.org/10.1007/3-540-15983-5\_13}, \sphinxhref{https://doi.org/10.1007/3-540-15983-5\_13}{doi:10.1007/3\sphinxhyphen{}540\sphinxhyphen{}15983\sphinxhyphen{}5\_13}%
\begin{footnote}[968]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/3-540-15983-5\_13}
%
\end{footnote}.
\bibitem[CP90]{zebibliography:id14}
\sphinxAtStartPar
Thierry Coquand and Christine Paulin. Inductively defined types. In \sphinxstyleemphasis{COLOG\sphinxhyphen{}88}, 50–66. Springer Berlin Heidelberg, 1990. URL: \sphinxurl{http://dx.doi.org/10.1007/3-540-52335-9\_47}, \sphinxhref{https://doi.org/10.1007/3-540-52335-9\_47}{doi:10.1007/3\sphinxhyphen{}540\sphinxhyphen{}52335\sphinxhyphen{}9\_47}%
\begin{footnote}[969]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/3-540-52335-9\_47}
%
\end{footnote}.
\bibitem[CT95]{zebibliography:id13}
\sphinxAtStartPar
Cristina Cornes and Delphine Terrasse. Automating inversion of inductive predicates in coq. In \sphinxstyleemphasis{TYPES}, 85–104. 1995.
\bibitem[CFC58]{zebibliography:id15}
\sphinxAtStartPar
Haskell B. Curry, Robert Feys, and William Craig. \sphinxstyleemphasis{Combinatory Logic}. Volume 1. North\sphinxhyphen{}Holland, 1958. §9E.
\bibitem[DM82]{zebibliography:id54}
\sphinxAtStartPar
Luis Damas and Robin Milner. Principal type\sphinxhyphen{}schemes for functional programs. In \sphinxstyleemphasis{Proceedings of the 9th ACM SIGPLAN\sphinxhyphen{}SIGACT Symposium on Principles of Programming Languages}, POPL '82, 207–212. New York, NY, USA, 1982. ACM. URL: \sphinxurl{http://doi.acm.org/10.1145/582153.582176}, \sphinxhref{https://doi.org/10.1145/582153.582176}{doi:10.1145/582153.582176}%
\begin{footnote}[970]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1145/582153.582176}
%
\end{footnote}.
\bibitem[dB72]{zebibliography:id5}
\sphinxAtStartPar
N.J. de Bruijn. Lambda\sphinxhyphen{}Calculus Notation with Nameless Dummies, a Tool for Automatic Formula Manipulation, with Application to the Church\sphinxhyphen{}Rosser Theorem. \sphinxstyleemphasis{Indag. Math.}, 1972.
\bibitem[Del00]{zebibliography:id18}
\sphinxAtStartPar
D. Delahaye. A Tactic Language for the System Coq. In \sphinxstyleemphasis{Proceedings of Logic for Programming and Automated Reasoning (LPAR), Reunion Island}, volume 1955 of Lecture Notes in Computer Science, 85–95. Springer\sphinxhyphen{}Verlag, November 2000. URL: \sphinxurl{http://www.lirmm.fr/\%7Edelahaye/papers/ltac\%20(LPAR\%2700).pdf}.
\bibitem[dC95]{zebibliography:id46}
\sphinxAtStartPar
R. di Cosmo. \sphinxstyleemphasis{Isomorphisms of Types: from λ\sphinxhyphen{}calculus to information retrieval and language design}. Progress in Theoretical Computer Science. Birkhauser, 1995. ISBN\sphinxhyphen{}0\sphinxhyphen{}8176\sphinxhyphen{}3763\sphinxhyphen{}X.
\bibitem[Dyc92]{zebibliography:id19}
\sphinxAtStartPar
Roy Dyckhoff. Contraction\sphinxhyphen{}free sequent calculi for intuitionistic logic. \sphinxstyleemphasis{The Journal of Symbolic Logic}, September 1992.
\bibitem[GCST19]{zebibliography:id21}
\sphinxAtStartPar
Gaëtan Gilbert, Jesper Cockx, Matthieu Sozeau, and Nicolas Tabareau. Definitional Proof Irrelevance Without K. \sphinxstyleemphasis{Proc. ACM Program. Lang.}, 3(POPL):3:1–3:28, 2019. URL: \sphinxurl{http://doi.acm.org/10.1145/3290316}.
\bibitem[Gimenez94]{zebibliography:id22}
\sphinxAtStartPar
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\sphinxhyphen{}Verlag, 1994. Extended version in LIP research report 95\sphinxhyphen{}07, ENS Lyon.
\bibitem[Gimenez95]{zebibliography:id25}
\sphinxAtStartPar
E. Giménez. An application of co\sphinxhyphen{}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–152. Springer\sphinxhyphen{}Verlag, 1995.
\bibitem[Gimenez98]{zebibliography:id23}
\sphinxAtStartPar
E. Giménez. A tutorial on recursive types in coq. Technical Report, INRIA, March 1998.
\bibitem[GimenezCasteran05]{zebibliography:id24}
\sphinxAtStartPar
E. Giménez and P. Castéran. A tutorial on {[}co\sphinxhyphen{}{]}inductive types in coq. available at \sphinxurl{http://coq.inria.fr/doc}, January 2005.
\bibitem[GMN+91]{zebibliography:id50}
\sphinxAtStartPar
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–4. 1991.
\bibitem[GLT89]{zebibliography:id26}
\sphinxAtStartPar
J.\sphinxhyphen{}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:id16}
\sphinxAtStartPar
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–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}[971]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1145/2034574.2034798}
%
\end{footnote}.
\bibitem[GregoireL02]{zebibliography:id52}
\sphinxAtStartPar
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\sphinxhyphen{}6, 2002.}, 235–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}[972]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1145/581478.581501}
%
\end{footnote}.
\bibitem[How80]{zebibliography:id27}
\sphinxAtStartPar
W.A. Howard. The formulae\sphinxhyphen{}as\sphinxhyphen{}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:id29}
\sphinxAtStartPar
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[Hue88]{zebibliography:id28}
\sphinxAtStartPar
Gérard Huet. Induction principles formalized in the calculus of constructions. In \sphinxstyleemphasis{Programming of Future Generation Computers. Elsevier Science}. Springer Berlin Heidelberg, 1988. URL: \sphinxurl{http://dx.doi.org/10.1007/3-540-17660-8\_62}, \sphinxhref{https://doi.org/10.1007/3-540-17660-8\_62}{doi:10.1007/3\sphinxhyphen{}540\sphinxhyphen{}17660\sphinxhyphen{}8\_62}%
\begin{footnote}[973]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/3-540-17660-8\_62}
%
\end{footnote}.
\bibitem[LW11]{zebibliography:id30}
\sphinxAtStartPar
Gyesik Lee and Benjamin Werner. Proof\sphinxhyphen{}irrelevant model of CC with predicative induction and judgmental equality. \sphinxstyleemphasis{Logical Methods in Computer Science}, 2011.
\bibitem[Ler90]{zebibliography:id31}
\sphinxAtStartPar
X. Leroy. The ZINC experiment: an economical implementation of the ML language. Technical Report 117, INRIA, 1990.
\bibitem[Let02]{zebibliography:id32}
\sphinxAtStartPar
P. Letouzey. A new extraction for coq. In \sphinxstyleemphasis{TYPES}. 2002. URL: \sphinxurl{http://www.irif.fr/~letouzey/download/extraction2002.pdf}.
\bibitem[LV97]{zebibliography:id33}
\sphinxAtStartPar
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\sphinxhyphen{}Verlag, 1997.
\bibitem[MT13]{zebibliography:id17}
\sphinxAtStartPar
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–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\sphinxhyphen{}3\sphinxhyphen{}642\sphinxhyphen{}39634\sphinxhyphen{}2\_5}%
\begin{footnote}[974]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/978-3-642-39634-2\_5}
%
\end{footnote}.
\bibitem[McB00]{zebibliography:id36}
\sphinxAtStartPar
Conor McBride. Elimination with a motive. In \sphinxstyleemphasis{TYPES}, 197–216. 2000.
\bibitem[Moh86]{zebibliography:id40}
\sphinxAtStartPar
Christine Mohring. Algorithm development in the calculus of constructions. In \sphinxstyleemphasis{LICS}, 84–91. 1986.
\bibitem[Mun94]{zebibliography:id38}
\sphinxAtStartPar
C. Muñoz. Démonstration automatique dans la logique propositionnelle intuitionniste. Master's thesis, DEA d'Informatique Fondamentale, Université Paris 7, September 1994.
\bibitem[Mye86]{zebibliography:id39}
\sphinxAtStartPar
Eugene Myers. An O(ND) difference algorithm and its variations. \sphinxstyleemphasis{Algorithmica}, 1986. URL: \sphinxurl{http://www.xmailserver.org/diff2.pdf}.
\bibitem[Par95]{zebibliography:id44}
\sphinxAtStartPar
C. Parent. Synthesizing proofs from programs in the Calculus of Inductive Constructions. In \sphinxstyleemphasis{Mathematics of Program Construction'95}, volume 947 of LNCS. Springer\sphinxhyphen{}Verlag, 1995.
\bibitem[PM93a]{zebibliography:id37}
\sphinxAtStartPar
C. Paulin\sphinxhyphen{}Mohring. Inductive Definitions in the System Coq \sphinxhyphen{} Rules and Properties. In M. Bezem and J.\sphinxhyphen{}F. Groote, editors, \sphinxstyleemphasis{Proceedings of the conference Typed Lambda Calculi and Applications}, number 664 in LNCS. Springer\sphinxhyphen{}Verlag, 1993. Also LIP research report 92\sphinxhyphen{}49, ENS Lyon.
\bibitem[PM89]{zebibliography:id41}
\sphinxAtStartPar
Christine Paulin\sphinxhyphen{}Mohring. Extracting ω's programs from proofs in the calculus of constructions. In \sphinxstyleemphasis{Proceedings of the 16th ACM SIGPLAN\sphinxhyphen{}SIGACT symposium on Principles of programming languages}, 89–104. ACM Press, 1989. URL: \sphinxurl{http://dx.doi.org/10.1145/75277.75285}, \sphinxhref{https://doi.org/10.1145/75277.75285}{doi:10.1145/75277.75285}%
\begin{footnote}[975]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1145/75277.75285}
%
\end{footnote}.
\bibitem[PM93b]{zebibliography:id42}
\sphinxAtStartPar
Christine Paulin\sphinxhyphen{}Mohring. Inductive definitions in the system coq rules and properties. In \sphinxstyleemphasis{International Conference on Typed Lambda Calculi and Applications}, 328–345. Springer\sphinxhyphen{}Verlag, 1993. URL: \sphinxurl{http://dx.doi.org/10.1007/bfb0037116}, \sphinxhref{https://doi.org/10.1007/bfb0037116}{doi:10.1007/bfb0037116}%
\begin{footnote}[976]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/bfb0037116}
%
\end{footnote}.
\bibitem[PPM89]{zebibliography:id43}
\sphinxAtStartPar
Frank Pfenning and Christine Paulin\sphinxhyphen{}Mohring. Inductively defined types in the calculus of constructions. In \sphinxstyleemphasis{International Conference on Mathematical Foundations of Programming Semantics}, 209–228. Springer\sphinxhyphen{}Verlag, 1989. URL: \sphinxurl{http://dx.doi.org/10.1007/bfb0040259}, \sphinxhref{https://doi.org/10.1007/bfb0040259}{doi:10.1007/bfb0040259}%
\begin{footnote}[977]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/bfb0040259}
%
\end{footnote}.
\bibitem[ROS98]{zebibliography:id47}
\sphinxAtStartPar
John Rushby, Sam Owre, and N. Shankar. Subtypes for specifications: predicate subtyping in PVS. \sphinxstyleemphasis{IEEE Transactions on Software Engineering}, 24(9):709–720, September 1998.
\bibitem[Soz07]{zebibliography:id48}
\sphinxAtStartPar
Matthieu Sozeau. Subset coercions in Coq. In \sphinxstyleemphasis{TYPES'06}, volume 4502 of LNCS, 237–252. Springer, 2007.
\bibitem[SO08]{zebibliography:id49}
\sphinxAtStartPar
Matthieu Sozeau and Nicolas Oury. First\sphinxhyphen{}Class Type Classes. In \sphinxstyleemphasis{TPHOLs'08}. 2008.
\bibitem[Vis01]{zebibliography:id35}
\sphinxAtStartPar
Eelco Visser. Stratego: A language for program transformation based on rewriting strategies. In \sphinxstyleemphasis{RTA}, volume 2051 of LNCS, 357–362. 2001.
\bibitem[VBT98]{zebibliography:id34}
\sphinxAtStartPar
Eelco Visser, Zine\sphinxhyphen{}El\sphinxhyphen{}Abidine Benaissa, and Andrew P. Tolmach. Building program optimizers with rewriting strategies. In \sphinxstyleemphasis{ICFP}, 13–26. 1998.
\bibitem[Wer94]{zebibliography:id51}
\sphinxAtStartPar
B. Werner. \sphinxstyleemphasis{Une théorie des constructions inductives}. Thèse de Doctorat, Université Paris 7, 1994.
\end{sphinxthebibliography}


\renewcommand{\indexname}{Glossary}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{a}
\item\relax\sphinxstyleindexentry{algebraic universe}\sphinxstyleindexpageref{language/core/sorts:\detokenize{term-algebraic-universe}}
\item\relax\sphinxstyleindexentry{alpha\sphinxhyphen{}convertible}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-alpha-convertible}}
\item\relax\sphinxstyleindexentry{attribute}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-attribute}}
\indexspace
\bigletter{b}
\item\relax\sphinxstyleindexentry{backtracking}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{term-backtracking}}
\item\relax\sphinxstyleindexentry{backtracking point}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{term-backtracking-point}}
\item\relax\sphinxstyleindexentry{backward reasoning}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{term-backward-reasoning}}
\item\relax\sphinxstyleindexentry{beta\sphinxhyphen{}redex}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-beta-redex}}
\item\relax\sphinxstyleindexentry{beta\sphinxhyphen{}reduction}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-beta-reduction}}
\item\relax\sphinxstyleindexentry{body}\sphinxstyleindexpageref{language/core/definitions:\detokenize{term-body}}
\item\relax\sphinxstyleindexentry{boolean attribute}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-boolean-attribute}}
\item\relax\sphinxstyleindexentry{branching}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{term-branching}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{Calculus of Inductive Constructions}\sphinxstyleindexpageref{language/cic:\detokenize{term-Calculus-of-Inductive-Constructions}}
\item\relax\sphinxstyleindexentry{command}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-command}}
\item\relax\sphinxstyleindexentry{conclusion}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-conclusion}}
\item\relax\sphinxstyleindexentry{constant}\sphinxstyleindexpageref{language/core/definitions:\detokenize{term-constant}}
\item\relax\sphinxstyleindexentry{contraction}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-contraction}}
\item\relax\sphinxstyleindexentry{convertible}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-convertible}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{de
Bruijn criterion}\sphinxstyleindexpageref{language/core/index:\detokenize{term-de
Bruijn-criterion}}
\item\relax\sphinxstyleindexentry{definitional equality}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-definitional-equality}}
\item\relax\sphinxstyleindexentry{delta\sphinxhyphen{}reduction}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-delta-reduction}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{equality}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-equality}}
\item\relax\sphinxstyleindexentry{eta\sphinxhyphen{}expansion}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-eta-expansion}}
\item\relax\sphinxstyleindexentry{existential variable}\sphinxstyleindexpageref{language/extensions/evars:\detokenize{term-existential-variable}}
\item\relax\sphinxstyleindexentry{expansion}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-expansion}}
\indexspace
\bigletter{f}
\item\relax\sphinxstyleindexentry{first success}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{term-first-success}}
\item\relax\sphinxstyleindexentry{flag}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-flag}}
\item\relax\sphinxstyleindexentry{forward reasoning}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{term-forward-reasoning}}
\indexspace
\bigletter{g}
\item\relax\sphinxstyleindexentry{global environment}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-global-environment}}
\item\relax\sphinxstyleindexentry{goal}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-goal}}
\indexspace
\bigletter{h}
\item\relax\sphinxstyleindexentry{head}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-head}}
\item\relax\sphinxstyleindexentry{head constant}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-head-constant}}
\item\relax\sphinxstyleindexentry{hypothesis}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-hypothesis}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{inhabited}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-inhabited}}
\item\relax\sphinxstyleindexentry{iota\sphinxhyphen{}reduction}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-iota-reduction}}
\indexspace
\bigletter{l}
\item\relax\sphinxstyleindexentry{left associative}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{term-left-associative}}
\item\relax\sphinxstyleindexentry{Leibniz equality}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-Leibniz-equality}}
\item\relax\sphinxstyleindexentry{local context}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-local-context}}
\indexspace
\bigletter{o}
\item\relax\sphinxstyleindexentry{occurrence}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{term-occurrence}}
\item\relax\sphinxstyleindexentry{opaque}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-opaque}}
\item\relax\sphinxstyleindexentry{option}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-option}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{prelude}\sphinxstyleindexpageref{language/coq-library:\detokenize{term-prelude}}
\item\relax\sphinxstyleindexentry{proof mode}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-proof-mode}}
\item\relax\sphinxstyleindexentry{proof state}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-proof-state}}
\item\relax\sphinxstyleindexentry{proof term}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-proof-term}}
\item\relax\sphinxstyleindexentry{proposition}\sphinxstyleindexpageref{language/core/sorts:\detokenize{term-proposition}}
\indexspace
\bigletter{q}
\item\relax\sphinxstyleindexentry{quotient}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-quotient}}
\item\relax\sphinxstyleindexentry{quotient set}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-quotient-set}}
\indexspace
\bigletter{r}
\item\relax\sphinxstyleindexentry{reduction}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-reduction}}
\item\relax\sphinxstyleindexentry{right associative}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{term-right-associative}}
\indexspace
\bigletter{s}
\item\relax\sphinxstyleindexentry{sentence}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-sentence}}
\item\relax\sphinxstyleindexentry{setoid}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-setoid}}
\item\relax\sphinxstyleindexentry{setoid equality}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-setoid-equality}}
\item\relax\sphinxstyleindexentry{shelved}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-shelved}}
\item\relax\sphinxstyleindexentry{sort}\sphinxstyleindexpageref{language/core/sorts:\detokenize{term-sort}}
\item\relax\sphinxstyleindexentry{standard library}\sphinxstyleindexpageref{language/coq-library:\detokenize{term-standard-library}}
\item\relax\sphinxstyleindexentry{strict proposition}\sphinxstyleindexpageref{language/core/sorts:\detokenize{term-strict-proposition}}
\item\relax\sphinxstyleindexentry{subgoal}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-subgoal}}
\indexspace
\bigletter{t}
\item\relax\sphinxstyleindexentry{table}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-table}}
\item\relax\sphinxstyleindexentry{tactic}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-tactic}}
\item\relax\sphinxstyleindexentry{term}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-term}}
\item\relax\sphinxstyleindexentry{transparent}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-transparent}}
\item\relax\sphinxstyleindexentry{type}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-type}}
\indexspace
\bigletter{u}
\item\relax\sphinxstyleindexentry{unfold}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-unfold}}
\item\relax\sphinxstyleindexentry{unshelved}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{term-unshelved}}
\indexspace
\bigletter{w}
\item\relax\sphinxstyleindexentry{weak\sphinxhyphen{}head normal form}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{term-weak-head-normal-form}}
\item\relax\sphinxstyleindexentry{well\sphinxhyphen{}typed}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-well-typed}}
\item\relax\sphinxstyleindexentry{witness}\sphinxstyleindexpageref{language/core/basic:\detokenize{term-witness}}
\indexspace
\bigletter{z}
\item\relax\sphinxstyleindexentry{zeta\sphinxhyphen{}reduction}\sphinxstyleindexpageref{language/core/conversion:\detokenize{term-zeta-reduction}}
\end{sphinxtheindex}
\renewcommand{\indexname}{Command Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{a}
\item\relax\sphinxstyleindexentry{Abort}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Abort}}
\item\relax\sphinxstyleindexentry{About}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.About}}
\item\relax\sphinxstyleindexentry{Add}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Add}}
\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 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{Add Zify}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:cmd.Add-Zify}}
\item\relax\sphinxstyleindexentry{Admit Obligations}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.Admit-Obligations}}
\item\relax\sphinxstyleindexentry{Admitted}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Admitted}}
\item\relax\sphinxstyleindexentry{Arguments}\sphinxstyleindexpageref{language/extensions/arguments-command:\detokenize{coq:cmd.Arguments}}
\item\relax\sphinxstyleindexentry{Axiom}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.Axiom}}
\item\relax\sphinxstyleindexentry{Axioms}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.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{Bind Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Bind-Scope}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{Canonical Structure}\sphinxstyleindexpageref{language/extensions/canonical:\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/core/coinductive:\detokenize{coq:cmd.CoFixpoint}}
\item\relax\sphinxstyleindexentry{CoInductive}\sphinxstyleindexpageref{language/core/coinductive:\detokenize{coq:cmd.CoInductive}}
\item\relax\sphinxstyleindexentry{Collection}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Collection}}
\item\relax\sphinxstyleindexentry{Combined Scheme}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:cmd.Combined-Scheme}}
\item\relax\sphinxstyleindexentry{Comments}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Comments}}
\item\relax\sphinxstyleindexentry{Compute}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:cmd.Compute}}
\item\relax\sphinxstyleindexentry{Conjecture}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.Conjecture}}
\item\relax\sphinxstyleindexentry{Conjectures}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.Conjectures}}
\item\relax\sphinxstyleindexentry{Constraint}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.Constraint}}
\item\relax\sphinxstyleindexentry{Context}\sphinxstyleindexpageref{language/core/sections:\detokenize{coq:cmd.Context}}
\item\relax\sphinxstyleindexentry{Corollary}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:cmd.Corollary}}
\item\relax\sphinxstyleindexentry{Create HintDb}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Create-HintDb}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{Declare Custom Entry}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Declare-Custom-Entry}}
\item\relax\sphinxstyleindexentry{Declare Instance}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.Declare-Instance}}
\item\relax\sphinxstyleindexentry{Declare Left Step}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\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/core/modules:\detokenize{coq:cmd.Declare-Module}}
\item\relax\sphinxstyleindexentry{Declare Morphism}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:cmd.Declare-Morphism}}
\item\relax\sphinxstyleindexentry{Declare Reduction}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:cmd.Declare-Reduction}}
\item\relax\sphinxstyleindexentry{Declare Right Step}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:cmd.Declare-Right-Step}}
\item\relax\sphinxstyleindexentry{Declare Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Declare-Scope}}
\item\relax\sphinxstyleindexentry{Defined}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Defined}}
\item\relax\sphinxstyleindexentry{Definition}\sphinxstyleindexpageref{language/core/definitions:\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 Dependent Inversion}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:cmd.Derive-Dependent-Inversion}}
\item\relax\sphinxstyleindexentry{Derive Dependent Inversion\_clear}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:cmd.Derive-Dependent-Inversion_clear}}
\item\relax\sphinxstyleindexentry{Derive Inversion}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:cmd.Derive-Inversion}}
\item\relax\sphinxstyleindexentry{Derive Inversion\_clear}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:cmd.Derive-Inversion_clear}}
\item\relax\sphinxstyleindexentry{Drop}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Drop}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{End}\sphinxstyleindexpageref{language/core/sections:\detokenize{coq:cmd.End}}
\item\relax\sphinxstyleindexentry{Eval}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:cmd.Eval}}
\item\relax\sphinxstyleindexentry{Example}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:cmd.Example}}
\item\relax\sphinxstyleindexentry{Existential}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\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{Existing Instances}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.Existing-Instances}}
\item\relax\sphinxstyleindexentry{Export}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:cmd.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}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.Extraction-Language}}
\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/core/definitions:\detokenize{coq:cmd.Fact}}
\item\relax\sphinxstyleindexentry{Fail}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Fail}}
\item\relax\sphinxstyleindexentry{Fixpoint}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:cmd.Fixpoint}}
\item\relax\sphinxstyleindexentry{Focus}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Focus}}
\item\relax\sphinxstyleindexentry{From … Require}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.From-_u2026-Require}}
\item\relax\sphinxstyleindexentry{Function}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:cmd.Function}}
\item\relax\sphinxstyleindexentry{Functional Scheme}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:cmd.Functional-Scheme}}
\indexspace
\bigletter{g}
\item\relax\sphinxstyleindexentry{Generalizable}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:cmd.Generalizable}}
\item\relax\sphinxstyleindexentry{Goal}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Goal}}
\item\relax\sphinxstyleindexentry{Grab Existential Variables}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Grab-Existential-Variables}}
\item\relax\sphinxstyleindexentry{Guarded}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Guarded}}
\indexspace
\bigletter{h}
\item\relax\sphinxstyleindexentry{Hint Constants}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Constants}}
\item\relax\sphinxstyleindexentry{Hint Constructors}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Constructors}}
\item\relax\sphinxstyleindexentry{Hint Cut}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Cut}}
\item\relax\sphinxstyleindexentry{Hint Extern}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Extern}}
\item\relax\sphinxstyleindexentry{Hint Immediate}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Immediate}}
\item\relax\sphinxstyleindexentry{Hint Mode}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Mode}}
\item\relax\sphinxstyleindexentry{Hint Opaque}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Opaque}}
\item\relax\sphinxstyleindexentry{Hint Resolve}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Resolve}}
\item\relax\sphinxstyleindexentry{Hint Rewrite}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Rewrite}}
\item\relax\sphinxstyleindexentry{Hint Transparent}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Transparent}}
\item\relax\sphinxstyleindexentry{Hint Unfold}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Unfold}}
\item\relax\sphinxstyleindexentry{Hint Variables}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Hint-Variables}}
\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/core/assumptions:\detokenize{coq:cmd.Hypotheses}}
\item\relax\sphinxstyleindexentry{Hypothesis}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.Hypothesis}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{Identity Coercion}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.Identity-Coercion}}
\item\relax\sphinxstyleindexentry{Implicit Type}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:cmd.Implicit-Type}}
\item\relax\sphinxstyleindexentry{Implicit Types}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:cmd.Implicit-Types}}
\item\relax\sphinxstyleindexentry{Import}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:cmd.Import}}
\item\relax\sphinxstyleindexentry{Include}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:cmd.Include}}
\item\relax\sphinxstyleindexentry{Include Type}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:cmd.Include-Type}}
\item\relax\sphinxstyleindexentry{Inductive}\sphinxstyleindexpageref{language/core/inductive:\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{Inspect}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Inspect}}
\item\relax\sphinxstyleindexentry{Instance}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.Instance}}
\indexspace
\bigletter{l}
\item\relax\sphinxstyleindexentry{Lemma}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:cmd.Lemma}}
\item\relax\sphinxstyleindexentry{Let}\sphinxstyleindexpageref{language/core/sections:\detokenize{coq:cmd.Let}}
\item\relax\sphinxstyleindexentry{Let CoFixpoint}\sphinxstyleindexpageref{language/core/sections:\detokenize{coq:cmd.Let-CoFixpoint}}
\item\relax\sphinxstyleindexentry{Let Fixpoint}\sphinxstyleindexpageref{language/core/sections:\detokenize{coq:cmd.Let-Fixpoint}}
\item\relax\sphinxstyleindexentry{Load}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Load}}
\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{Locate Ltac}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Locate-Ltac}}
\item\relax\sphinxstyleindexentry{Locate Module}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Locate-Module}}
\item\relax\sphinxstyleindexentry{Locate Term}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Locate-Term}}
\item\relax\sphinxstyleindexentry{Ltac}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.Ltac}}
\item\relax\sphinxstyleindexentry{Ltac2}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:cmd.Ltac2}}
\item\relax\sphinxstyleindexentry{Ltac2 Eval}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:cmd.Ltac2-Eval}}
\item\relax\sphinxstyleindexentry{Ltac2 external}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:cmd.Ltac2-external}}
\item\relax\sphinxstyleindexentry{Ltac2 Notation}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:cmd.Ltac2-Notation}}
\item\relax\sphinxstyleindexentry{Ltac2 Notation (abbreviation)}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:cmd.Ltac2-Notation-(abbreviation)}}
\item\relax\sphinxstyleindexentry{Ltac2 Set}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:cmd.Ltac2-Set}}
\item\relax\sphinxstyleindexentry{Ltac2 Type}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:cmd.Ltac2-Type}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{Module}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:cmd.Module}}
\item\relax\sphinxstyleindexentry{Module Type}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:cmd.Module-Type}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{Next Obligation}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.Next-Obligation}}
\item\relax\sphinxstyleindexentry{Notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Notation}}
\item\relax\sphinxstyleindexentry{Notation (abbreviation)}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Notation-(abbreviation)}}
\item\relax\sphinxstyleindexentry{Number Notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Number-Notation}}
\indexspace
\bigletter{o}
\item\relax\sphinxstyleindexentry{Obligation}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.Obligation}}
\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{proofs/writing-proofs/equality:\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{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Optimize-Heap}}
\item\relax\sphinxstyleindexentry{Optimize Proof}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Optimize-Proof}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{Parameter}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.Parameter}}
\item\relax\sphinxstyleindexentry{Parameters}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.Parameters}}
\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{Primitive}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Primitive}}
\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:cmd.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/extensions/canonical:\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 Custom Grammar}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Print-Custom-Grammar}}
\item\relax\sphinxstyleindexentry{Print Debug GC}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Print-Debug-GC}}
\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{proofs/automatic-tactics/logic:\detokenize{coq:cmd.Print-Firstorder-Solver}}
\item\relax\sphinxstyleindexentry{Print Grammar}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Print-Grammar}}
\item\relax\sphinxstyleindexentry{Print Graph}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.Print-Graph}}
\item\relax\sphinxstyleindexentry{Print Hint}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Print-Hint}}
\item\relax\sphinxstyleindexentry{Print HintDb}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Print-HintDb}}
\item\relax\sphinxstyleindexentry{Print Implicit}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:cmd.Print-Implicit}}
\item\relax\sphinxstyleindexentry{Print Instances}\sphinxstyleindexpageref{addendum/type-classes:\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/core/modules:\detokenize{coq:cmd.Print-Module}}
\item\relax\sphinxstyleindexentry{Print Module Type}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:cmd.Print-Module-Type}}
\item\relax\sphinxstyleindexentry{Print Opaque Dependencies}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Print-Opaque-Dependencies}}
\item\relax\sphinxstyleindexentry{Print Options}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Print-Options}}
\item\relax\sphinxstyleindexentry{Print Rewrite HintDb}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Print-Rewrite-HintDb}}
\item\relax\sphinxstyleindexentry{Print Rings}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:cmd.Print-Rings}}
\item\relax\sphinxstyleindexentry{Print Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Print-Scope}}
\item\relax\sphinxstyleindexentry{Print Scopes}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Print-Scopes}}
\item\relax\sphinxstyleindexentry{Print Section}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Print-Section}}
\item\relax\sphinxstyleindexentry{Print Strategies}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:cmd.Print-Strategies}}
\item\relax\sphinxstyleindexentry{Print Strategy}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:cmd.Print-Strategy}}
\item\relax\sphinxstyleindexentry{Print Table}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Print-Table}}
\item\relax\sphinxstyleindexentry{Print Tables}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Print-Tables}}
\item\relax\sphinxstyleindexentry{Print Transparent Dependencies}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Print-Transparent-Dependencies}}
\item\relax\sphinxstyleindexentry{Print Typing Flags}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Print-Typing-Flags}}
\item\relax\sphinxstyleindexentry{Print Universes}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.Print-Universes}}
\item\relax\sphinxstyleindexentry{Print Visibility}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Print-Visibility}}
\item\relax\sphinxstyleindexentry{Proof}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Proof}}
\item\relax\sphinxstyleindexentry{Proof `term`}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Proof-`term`}}
\item\relax\sphinxstyleindexentry{Proof using}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Proof-using}}
\item\relax\sphinxstyleindexentry{Proof with}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:cmd.Proof-with}}
\item\relax\sphinxstyleindexentry{Property}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:cmd.Property}}
\item\relax\sphinxstyleindexentry{Proposition}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:cmd.Proposition}}
\item\relax\sphinxstyleindexentry{Pwd}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Pwd}}
\indexspace
\bigletter{q}
\item\relax\sphinxstyleindexentry{Qed}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\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/core/records:\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{Register}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Register}}
\item\relax\sphinxstyleindexentry{Register Inline}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Register-Inline}}
\item\relax\sphinxstyleindexentry{Remark}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:cmd.Remark}}
\item\relax\sphinxstyleindexentry{Remove}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Remove}}
\item\relax\sphinxstyleindexentry{Remove Hints}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\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:cmd.Require-Export}}
\item\relax\sphinxstyleindexentry{Require Import}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Require-Import}}
\item\relax\sphinxstyleindexentry{Reserved Infix}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Reserved-Infix}}
\item\relax\sphinxstyleindexentry{Reserved Notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Reserved-Notation}}
\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 Initial}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.Reset-Initial}}
\item\relax\sphinxstyleindexentry{Reset Ltac Profile}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.Reset-Ltac-Profile}}
\item\relax\sphinxstyleindexentry{Restart}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Restart}}
\indexspace
\bigletter{s}
\item\relax\sphinxstyleindexentry{Save}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Save}}
\item\relax\sphinxstyleindexentry{Scheme}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:cmd.Scheme}}
\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{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/core/sections:\detokenize{coq:cmd.Section}}
\item\relax\sphinxstyleindexentry{Separate Extraction}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.Separate-Extraction}}
\item\relax\sphinxstyleindexentry{Set}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Set}}
\item\relax\sphinxstyleindexentry{Show}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show}}
\item\relax\sphinxstyleindexentry{Show Conjectures}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show-Conjectures}}
\item\relax\sphinxstyleindexentry{Show Existentials}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show-Existentials}}
\item\relax\sphinxstyleindexentry{Show Goal}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show-Goal}}
\item\relax\sphinxstyleindexentry{Show Intro}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show-Intro}}
\item\relax\sphinxstyleindexentry{Show Intros}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show-Intros}}
\item\relax\sphinxstyleindexentry{Show Lia Profile}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:cmd.Show-Lia-Profile}}
\item\relax\sphinxstyleindexentry{Show Ltac Profile}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.Show-Ltac-Profile}}
\item\relax\sphinxstyleindexentry{Show Match}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show-Match}}
\item\relax\sphinxstyleindexentry{Show Obligation Tactic}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.Show-Obligation-Tactic}}
\item\relax\sphinxstyleindexentry{Show Proof}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show-Proof}}
\item\relax\sphinxstyleindexentry{Show Universes}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Show-Universes}}
\item\relax\sphinxstyleindexentry{Show Zify}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:cmd.Show-Zify}}
\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{proofs/writing-proofs/equality:\detokenize{coq:cmd.Strategy}}
\item\relax\sphinxstyleindexentry{String Notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.String-Notation}}
\item\relax\sphinxstyleindexentry{Structure}\sphinxstyleindexpageref{language/core/records:\detokenize{coq:cmd.Structure}}
\item\relax\sphinxstyleindexentry{SubClass}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.SubClass}}
\indexspace
\bigletter{t}
\item\relax\sphinxstyleindexentry{Tactic Notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.Tactic-Notation}}
\item\relax\sphinxstyleindexentry{Test}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Test}}
\item\relax\sphinxstyleindexentry{Theorem}\sphinxstyleindexpageref{language/core/definitions:\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{proofs/writing-proofs/equality:\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{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Undo}}
\item\relax\sphinxstyleindexentry{Unfocus}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Unfocus}}
\item\relax\sphinxstyleindexentry{Unfocused}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Unfocused}}
\item\relax\sphinxstyleindexentry{Universe}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.Universe}}
\item\relax\sphinxstyleindexentry{Unset}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:cmd.Unset}}
\item\relax\sphinxstyleindexentry{Unshelve}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:cmd.Unshelve}}
\indexspace
\bigletter{v}
\item\relax\sphinxstyleindexentry{Variable}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.Variable}}
\item\relax\sphinxstyleindexentry{Variables}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:cmd.Variables}}
\item\relax\sphinxstyleindexentry{Variant}\sphinxstyleindexpageref{language/core/variants:\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{=>}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.=>}}
\indexspace
\bigletter{{[}}
\item\relax\sphinxstyleindexentry{{[} … | … | … {]} (dispatch)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn._-_u2026-|-_u2026-|-_u2026-_-(dispatch)}}
\item\relax\sphinxstyleindexentry{{[}> … | … | … {]} (dispatch)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn._>-_u2026-|-_u2026-|-_u2026-_-(dispatch)}}
\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{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-_u2026-in}}
\item\relax\sphinxstyleindexentry{apply … in … as}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.apply-_u2026-in-_u2026-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{proofs/automatic-tactics/auto:\detokenize{coq:tacn.auto}}
\item\relax\sphinxstyleindexentry{autoapply}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:tacn.autoapply}}
\item\relax\sphinxstyleindexentry{autorewrite}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.autorewrite}}
\item\relax\sphinxstyleindexentry{autounfold}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.autounfold}}
\indexspace
\bigletter{b}
\item\relax\sphinxstyleindexentry{bfs eauto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.bfs-eauto}}
\item\relax\sphinxstyleindexentry{btauto}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.case}}
\item\relax\sphinxstyleindexentry{case (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.case-(ssreflect)}}
\item\relax\sphinxstyleindexentry{cbn}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.cbn}}
\item\relax\sphinxstyleindexentry{cbv}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.cbv}}
\item\relax\sphinxstyleindexentry{change}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.change}}
\item\relax\sphinxstyleindexentry{change\_no\_check}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.change_no_check}}
\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:tacn.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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.cofix}}
\item\relax\sphinxstyleindexentry{compare}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.compare}}
\item\relax\sphinxstyleindexentry{compute}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.compute}}
\item\relax\sphinxstyleindexentry{congr}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.congr}}
\item\relax\sphinxstyleindexentry{congruence}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:tacn.congruence}}
\item\relax\sphinxstyleindexentry{constr\_eq}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.constr_eq}}
\item\relax\sphinxstyleindexentry{constr\_eq\_strict}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.constr_eq_strict}}
\item\relax\sphinxstyleindexentry{constructor}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.constructor}}
\item\relax\sphinxstyleindexentry{context}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.context}}
\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{proofs/writing-proofs/equality:\detokenize{coq:tacn.cutrewrite}}
\item\relax\sphinxstyleindexentry{cycle}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:tacn.cycle}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{debug auto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.debug-auto}}
\item\relax\sphinxstyleindexentry{debug eauto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.debug-eauto}}
\item\relax\sphinxstyleindexentry{debug trivial}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.debug-trivial}}
\item\relax\sphinxstyleindexentry{decide equality}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.decide-equality}}
\item\relax\sphinxstyleindexentry{decompose}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.decompose}}
\item\relax\sphinxstyleindexentry{dependent destruction}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.dependent-destruction}}
\item\relax\sphinxstyleindexentry{dependent induction}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.dependent-induction}}
\item\relax\sphinxstyleindexentry{dependent inversion}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.dependent-inversion}}
\item\relax\sphinxstyleindexentry{dependent inversion … with …}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.dependent-inversion-_u2026-with-_u2026}}
\item\relax\sphinxstyleindexentry{dependent rewrite \sphinxhyphen{}>}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.dependent-rewrite-->}}
\item\relax\sphinxstyleindexentry{dependent rewrite <\sphinxhyphen{}}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.dependent-rewrite-<-}}
\item\relax\sphinxstyleindexentry{destruct}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.destruct}}
\item\relax\sphinxstyleindexentry{destruct … eqn:}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.destruct-_u2026-eqn:}}
\item\relax\sphinxstyleindexentry{dintuition}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:tacn.dintuition}}
\item\relax\sphinxstyleindexentry{discriminate}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{dtauto}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:tacn.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{proofs/automatic-tactics/auto:\detokenize{coq:tacn.easy}}
\item\relax\sphinxstyleindexentry{eauto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.eauto}}
\item\relax\sphinxstyleindexentry{ecase}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.ecase}}
\item\relax\sphinxstyleindexentry{econstructor}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.econstructor}}
\item\relax\sphinxstyleindexentry{edestruct}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.edestruct}}
\item\relax\sphinxstyleindexentry{ediscriminate}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.ediscriminate}}
\item\relax\sphinxstyleindexentry{eelim}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.eexists}}
\item\relax\sphinxstyleindexentry{einduction}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.einduction}}
\item\relax\sphinxstyleindexentry{einjection}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.einjection}}
\item\relax\sphinxstyleindexentry{eintros}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.eintros}}
\item\relax\sphinxstyleindexentry{eleft}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.eleft}}
\item\relax\sphinxstyleindexentry{elim}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.elim-_u2026-with}}
\item\relax\sphinxstyleindexentry{elimtype}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{epose proof}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.epose-proof}}
\item\relax\sphinxstyleindexentry{eremember}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eremember}}
\item\relax\sphinxstyleindexentry{erewrite}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.erewrite}}
\item\relax\sphinxstyleindexentry{eright}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.eright}}
\item\relax\sphinxstyleindexentry{eset}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eset}}
\item\relax\sphinxstyleindexentry{esimplify\_eq}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.esimplify_eq}}
\item\relax\sphinxstyleindexentry{esplit}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.esplit}}
\item\relax\sphinxstyleindexentry{etransitivity}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.etransitivity}}
\item\relax\sphinxstyleindexentry{eval}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.eval}}
\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{exact (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.exact-(ssreflect)}}
\item\relax\sphinxstyleindexentry{exact\_no\_check}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.exact_no_check}}
\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.exists}}
\indexspace
\bigletter{f}
\item\relax\sphinxstyleindexentry{f\_equal}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.f_equal}}
\item\relax\sphinxstyleindexentry{fail}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.fail}}
\item\relax\sphinxstyleindexentry{field}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:tacn.field}}
\item\relax\sphinxstyleindexentry{field\_simplify}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:tacn.field_simplify}}
\item\relax\sphinxstyleindexentry{field\_simplify\_eq}\sphinxstyleindexpageref{addendum/ring:\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:tacv.first-last}}
\item\relax\sphinxstyleindexentry{firstorder}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:tacn.firstorder}}
\item\relax\sphinxstyleindexentry{fix}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.fix}}
\item\relax\sphinxstyleindexentry{fold}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.fold}}
\item\relax\sphinxstyleindexentry{fresh}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.fresh}}
\item\relax\sphinxstyleindexentry{fun}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.fun}}
\item\relax\sphinxstyleindexentry{functional induction}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:tacn.functional-induction}}
\item\relax\sphinxstyleindexentry{functional inversion}\sphinxstyleindexpageref{using/libraries/funind:\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:tacn.generally-have}}
\item\relax\sphinxstyleindexentry{gfail}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.gfail}}
\item\relax\sphinxstyleindexentry{give\_up}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\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{proofs/writing-proofs/equality:\detokenize{coq:tacn.hnf}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{idtac}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.idtac}}
\item\relax\sphinxstyleindexentry{if\sphinxhyphen{}then\sphinxhyphen{}else (Ltac2)}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:tacn.if-then-else-(Ltac2)}}
\item\relax\sphinxstyleindexentry{in}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.in}}
\item\relax\sphinxstyleindexentry{induction}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.induction}}
\item\relax\sphinxstyleindexentry{induction … using …}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.induction-_u2026-using-_u2026}}
\item\relax\sphinxstyleindexentry{info\_auto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.info_auto}}
\item\relax\sphinxstyleindexentry{info\_eauto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.info_eauto}}
\item\relax\sphinxstyleindexentry{info\_trivial}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.info_trivial}}
\item\relax\sphinxstyleindexentry{infoH}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.infoH}}
\item\relax\sphinxstyleindexentry{injection}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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-_u2026}}
\item\relax\sphinxstyleindexentry{intuition}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:tacn.intuition}}
\item\relax\sphinxstyleindexentry{inversion}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.inversion}}
\item\relax\sphinxstyleindexentry{inversion ... using ...}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.inversion-...-using-...}}
\item\relax\sphinxstyleindexentry{inversion\_clear}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.inversion_clear}}
\item\relax\sphinxstyleindexentry{inversion\_sigma}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.inversion_sigma}}
\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:tacv.last-first}}
\item\relax\sphinxstyleindexentry{lazy}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.lazy}}
\item\relax\sphinxstyleindexentry{lazy\_match!}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:tacn.lazy_match!}}
\item\relax\sphinxstyleindexentry{lazy\_match! goal}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:tacn.lazy_match!-goal}}
\item\relax\sphinxstyleindexentry{lazymatch}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.lazymatch}}
\item\relax\sphinxstyleindexentry{lazymatch goal}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.lazymatch-goal}}
\item\relax\sphinxstyleindexentry{left}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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\sphinxhyphen{}seq}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.ltac-seq}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{match}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.match}}
\item\relax\sphinxstyleindexentry{match (Ltac2)}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:tacn.match-(Ltac2)}}
\item\relax\sphinxstyleindexentry{match goal}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.match-goal}}
\item\relax\sphinxstyleindexentry{match!}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:tacn.match!}}
\item\relax\sphinxstyleindexentry{match! goal}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:tacn.match!-goal}}
\item\relax\sphinxstyleindexentry{move}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.move}}
\item\relax\sphinxstyleindexentry{move (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.move-(ssreflect)}}
\item\relax\sphinxstyleindexentry{move … at bottom}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.move-_u2026-at-bottom}}
\item\relax\sphinxstyleindexentry{move … at top}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.move-_u2026-at-top}}
\item\relax\sphinxstyleindexentry{move … before …}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.move-_u2026-before-_u2026}}
\item\relax\sphinxstyleindexentry{multi\_match!}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:tacn.multi_match!}}
\item\relax\sphinxstyleindexentry{multi\_match! goal}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:tacn.multi_match!-goal}}
\item\relax\sphinxstyleindexentry{multimatch}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.multimatch}}
\item\relax\sphinxstyleindexentry{multimatch goal}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.multimatch-goal}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{native\_cast\_no\_check}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.native_cast_no_check}}
\item\relax\sphinxstyleindexentry{native\_compute}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.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{proofs/automatic-tactics/auto:\detokenize{coq:tacn.now}}
\item\relax\sphinxstyleindexentry{now\_show}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.now_show}}
\item\relax\sphinxstyleindexentry{nra}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:tacn.nra}}
\item\relax\sphinxstyleindexentry{nsatz}\sphinxstyleindexpageref{addendum/nsatz:\detokenize{coq:tacn.nsatz}}
\item\relax\sphinxstyleindexentry{numgoals}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.numgoals}}
\indexspace
\bigletter{o}
\item\relax\sphinxstyleindexentry{once}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.once}}
\item\relax\sphinxstyleindexentry{only}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.only}}
\item\relax\sphinxstyleindexentry{optimize\_heap}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.optimize_heap}}
\item\relax\sphinxstyleindexentry{over}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.over}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{pattern}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\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{r}
\item\relax\sphinxstyleindexentry{rapply}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.rapply}}
\item\relax\sphinxstyleindexentry{red}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.red}}
\item\relax\sphinxstyleindexentry{refine}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.refine}}
\item\relax\sphinxstyleindexentry{reflexivity}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\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{proofs/writing-proofs/equality:\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{proofs/writing-proofs/proof-mode:\detokenize{coq:tacn.revgoals}}
\item\relax\sphinxstyleindexentry{rewrite}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.rewrite}}
\item\relax\sphinxstyleindexentry{rewrite (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.rewrite-(ssreflect)}}
\item\relax\sphinxstyleindexentry{rewrite *}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.rewrite-*}}
\item\relax\sphinxstyleindexentry{rewrite\_db}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.rewrite_db}}
\item\relax\sphinxstyleindexentry{rewrite\_strat}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacn.rewrite_strat}}
\item\relax\sphinxstyleindexentry{right}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.right}}
\item\relax\sphinxstyleindexentry{ring}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:tacn.ring}}
\item\relax\sphinxstyleindexentry{ring\_simplify}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:tacn.ring_simplify}}
\item\relax\sphinxstyleindexentry{rtauto}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\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:tacn.setoid_reflexivity}}
\item\relax\sphinxstyleindexentry{setoid\_replace}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacn.setoid_replace}}
\item\relax\sphinxstyleindexentry{setoid\_rewrite}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacn.setoid_rewrite}}
\item\relax\sphinxstyleindexentry{setoid\_symmetry}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacn.setoid_symmetry}}
\item\relax\sphinxstyleindexentry{setoid\_transitivity}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacn.setoid_transitivity}}
\item\relax\sphinxstyleindexentry{shelve}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:tacn.shelve}}
\item\relax\sphinxstyleindexentry{shelve\_unifiable}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:tacn.shelve_unifiable}}
\item\relax\sphinxstyleindexentry{show ltac profile}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.show-ltac-profile}}
\item\relax\sphinxstyleindexentry{simpl}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.simpl}}
\item\relax\sphinxstyleindexentry{simple apply}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.simple-apply}}
\item\relax\sphinxstyleindexentry{simple destruct}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacv.simple-induction}}
\item\relax\sphinxstyleindexentry{simple inversion}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{simple subst}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.simple-subst}}
\item\relax\sphinxstyleindexentry{simplify\_eq}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:tacn.simplify_eq}}
\item\relax\sphinxstyleindexentry{solve}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.solve}}
\item\relax\sphinxstyleindexentry{solve\_constraints}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.solve_constraints}}
\item\relax\sphinxstyleindexentry{specialize}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.specialize}}
\item\relax\sphinxstyleindexentry{split}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{proofs/writing-proofs/equality:\detokenize{coq:tacn.stepl}}
\item\relax\sphinxstyleindexentry{stepr}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.stepr}}
\item\relax\sphinxstyleindexentry{stop ltac profiling}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.stop-ltac-profiling}}
\item\relax\sphinxstyleindexentry{subst}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.subst}}
\item\relax\sphinxstyleindexentry{substitute}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.substitute}}
\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:tacn.suffices}}
\item\relax\sphinxstyleindexentry{swap}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:tacn.swap}}
\item\relax\sphinxstyleindexentry{symmetry}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.symmetry}}
\indexspace
\bigletter{t}
\item\relax\sphinxstyleindexentry{tauto}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\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{proofs/writing-proofs/equality:\detokenize{coq:tacn.transitivity}}
\item\relax\sphinxstyleindexentry{transparent\_abstract}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.transparent_abstract}}
\item\relax\sphinxstyleindexentry{trivial}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:tacn.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{type of}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.type-of}}
\item\relax\sphinxstyleindexentry{type\_term}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.type_term}}
\item\relax\sphinxstyleindexentry{typeclasses eauto}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:tacn.typeclasses-eauto}}
\indexspace
\bigletter{u}
\item\relax\sphinxstyleindexentry{under}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.under}}
\item\relax\sphinxstyleindexentry{unfold}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\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}}
\item\relax\sphinxstyleindexentry{unshelve}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:tacn.unshelve}}
\indexspace
\bigletter{v}
\item\relax\sphinxstyleindexentry{vm\_cast\_no\_check}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.vm_cast_no_check}}
\item\relax\sphinxstyleindexentry{vm\_compute}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.vm_compute}}
\indexspace
\bigletter{w}
\item\relax\sphinxstyleindexentry{with\_strategy}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:tacn.with_strategy}}
\item\relax\sphinxstyleindexentry{without loss}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.without-loss}}
\item\relax\sphinxstyleindexentry{wlog}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.wlog}}
\indexspace
\bigletter{z}
\item\relax\sphinxstyleindexentry{zify}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:tacn.zify}}
\indexspace
\bigletter{\{}
\item\relax\sphinxstyleindexentry{\{}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:tacn._}}
\indexspace
\bigletter{|}
\item\relax\sphinxstyleindexentry{|| (first tactic making progress)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.||-(first-tactic-making-progress)}}
\indexspace
\bigletter{\}}
\item\relax\sphinxstyleindexentry{\}}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:tacn._}}
\indexspace
\bigletter{…}
\item\relax\sphinxstyleindexentry{… : … (goal selector)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn._u2026-:-_u2026-(goal-selector)}}
\item\relax\sphinxstyleindexentry{… : … (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn._u2026-:-_u2026-(ssreflect)}}
\end{sphinxtheindex}
\renewcommand{\indexname}{Flags, options and Tables Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{a}
\item\relax\sphinxstyleindexentry{Allow StrictProp}\sphinxstyleindexpageref{addendum/sprop:\detokenize{coq:flag.Allow-StrictProp}}
\item\relax\sphinxstyleindexentry{Asymmetric Patterns}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:flag.Asymmetric-Patterns}}
\item\relax\sphinxstyleindexentry{Auto Template Polymorphism}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:flag.Auto-Template-Polymorphism}}
\indexspace
\bigletter{b}
\item\relax\sphinxstyleindexentry{Boolean Equality Schemes}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:flag.Boolean-Equality-Schemes}}
\item\relax\sphinxstyleindexentry{Bullet Behavior}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:opt.Bullet-Behavior}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{Case Analysis Schemes}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:flag.Case-Analysis-Schemes}}
\item\relax\sphinxstyleindexentry{Contextual Implicit}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:flag.Contextual-Implicit}}
\item\relax\sphinxstyleindexentry{Coqtop Exit On Error}\sphinxstyleindexpageref{practical-tools/coq-commands:\detokenize{coq:flag.Coqtop-Exit-On-Error}}
\item\relax\sphinxstyleindexentry{Cumulative StrictProp}\sphinxstyleindexpageref{addendum/sprop:\detokenize{coq:flag.Cumulative-StrictProp}}
\item\relax\sphinxstyleindexentry{Cumulativity Weak Constraints}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:flag.Cumulativity-Weak-Constraints}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{Debug}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:opt.Debug}}
\item\relax\sphinxstyleindexentry{Debug Auto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:flag.Debug-Auto}}
\item\relax\sphinxstyleindexentry{Debug Eauto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:flag.Debug-Eauto}}
\item\relax\sphinxstyleindexentry{Debug Ssreflect}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:flag.Debug-Ssreflect}}
\item\relax\sphinxstyleindexentry{Debug SsrMatching}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:flag.Debug-SsrMatching}}
\item\relax\sphinxstyleindexentry{Debug Trivial}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:flag.Debug-Trivial}}
\item\relax\sphinxstyleindexentry{Decidable Equality Schemes}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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 Mode}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:opt.Default-Proof-Mode}}
\item\relax\sphinxstyleindexentry{Default Proof Using}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:opt.Default-Proof-Using}}
\item\relax\sphinxstyleindexentry{Default Timeout}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:opt.Default-Timeout}}
\item\relax\sphinxstyleindexentry{Definitional UIP}\sphinxstyleindexpageref{addendum/sprop:\detokenize{coq:flag.Definitional-UIP}}
\item\relax\sphinxstyleindexentry{Diffs}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:opt.Diffs}}
\item\relax\sphinxstyleindexentry{Dump Arith}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:opt.Dump-Arith}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{Elaboration StrictProp Cumulativity}\sphinxstyleindexpageref{addendum/sprop:\detokenize{coq:flag.Elaboration-StrictProp-Cumulativity}}
\item\relax\sphinxstyleindexentry{Elimination Schemes}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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 File Comment}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:opt.Extraction-File-Comment}}
\item\relax\sphinxstyleindexentry{Extraction Flag}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:opt.Extraction-Flag}}
\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}}
\item\relax\sphinxstyleindexentry{Extraction TypeExpand}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:flag.Extraction-TypeExpand}}
\indexspace
\bigletter{f}
\item\relax\sphinxstyleindexentry{Fast Name Printing}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.Fast-Name-Printing}}
\item\relax\sphinxstyleindexentry{Firstorder Depth}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:opt.Firstorder-Depth}}
\item\relax\sphinxstyleindexentry{Firstorder Solver}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:opt.Firstorder-Solver}}
\indexspace
\bigletter{g}
\item\relax\sphinxstyleindexentry{Guard Checking}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.Guard-Checking}}
\indexspace
\bigletter{h}
\item\relax\sphinxstyleindexentry{Hyps Limit}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:opt.Hyps-Limit}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{Implicit Arguments}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:flag.Implicit-Arguments}}
\item\relax\sphinxstyleindexentry{Info Auto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:flag.Info-Auto}}
\item\relax\sphinxstyleindexentry{Info Eauto}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\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{proofs/automatic-tactics/auto:\detokenize{coq:flag.Info-Trivial}}
\item\relax\sphinxstyleindexentry{Instance Generalized Output}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.Instance-Generalized-Output}}
\item\relax\sphinxstyleindexentry{Intuition Negation Unfolding}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:flag.Intuition-Negation-Unfolding}}
\indexspace
\bigletter{k}
\item\relax\sphinxstyleindexentry{Keep Proof Equalities}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:flag.Keep-Proof-Equalities}}
\item\relax\sphinxstyleindexentry{Keyed Unification}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:flag.Keyed-Unification}}
\indexspace
\bigletter{l}
\item\relax\sphinxstyleindexentry{Lia Cache}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:flag.Lia-Cache}}
\item\relax\sphinxstyleindexentry{Loose Hint Behavior}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:opt.Loose-Hint-Behavior}}
\item\relax\sphinxstyleindexentry{Ltac Backtrace}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:flag.Ltac-Backtrace}}
\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}}
\item\relax\sphinxstyleindexentry{Ltac2 Backtrace}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:flag.Ltac2-Backtrace}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{Mangle Names}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.Mangle-Names}}
\item\relax\sphinxstyleindexentry{Mangle Names Prefix}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:opt.Mangle-Names-Prefix}}
\item\relax\sphinxstyleindexentry{Maximal Implicit Insertion}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:flag.Maximal-Implicit-Insertion}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{NativeCompute Profile Filename}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:opt.NativeCompute-Profile-Filename}}
\item\relax\sphinxstyleindexentry{NativeCompute Profiling}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:flag.NativeCompute-Profiling}}
\item\relax\sphinxstyleindexentry{NativeCompute Timing}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:flag.NativeCompute-Timing}}
\item\relax\sphinxstyleindexentry{Nested Proofs Allowed}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:flag.Nested-Proofs-Allowed}}
\item\relax\sphinxstyleindexentry{Nia Cache}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:flag.Nia-Cache}}
\item\relax\sphinxstyleindexentry{Nonrecursive Elimination Schemes}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:flag.Nonrecursive-Elimination-Schemes}}
\item\relax\sphinxstyleindexentry{Nra Cache}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:flag.Nra-Cache}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{Parsing Explicit}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:flag.Parsing-Explicit}}
\item\relax\sphinxstyleindexentry{Polymorphic Inductive Cumulativity}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:flag.Polymorphic-Inductive-Cumulativity}}
\item\relax\sphinxstyleindexentry{Positivity Checking}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.Positivity-Checking}}
\item\relax\sphinxstyleindexentry{Primitive Projections}\sphinxstyleindexpageref{language/core/records:\detokenize{coq:flag.Primitive-Projections}}
\item\relax\sphinxstyleindexentry{Printing All}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.Printing-All}}
\item\relax\sphinxstyleindexentry{Printing Allow Match Default Clause}\sphinxstyleindexpageref{language/extensions/match:\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/core/records:\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/extensions/evars:\detokenize{coq:flag.Printing-Existential-Instances}}
\item\relax\sphinxstyleindexentry{Printing Factorizable Match Patterns}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:flag.Printing-Factorizable-Match-Patterns}}
\item\relax\sphinxstyleindexentry{Printing Float}\sphinxstyleindexpageref{language/coq-library:\detokenize{coq:flag.Printing-Float}}
\item\relax\sphinxstyleindexentry{Printing Goal Names}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:flag.Printing-Goal-Names}}
\item\relax\sphinxstyleindexentry{Printing If}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:table.Printing-If}}
\item\relax\sphinxstyleindexentry{Printing Implicit}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:flag.Printing-Implicit}}
\item\relax\sphinxstyleindexentry{Printing Implicit Defensive}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:flag.Printing-Implicit-Defensive}}
\item\relax\sphinxstyleindexentry{Printing Let}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:table.Printing-Let}}
\item\relax\sphinxstyleindexentry{Printing Matching}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:flag.Printing-Matching}}
\item\relax\sphinxstyleindexentry{Printing Notations}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:flag.Printing-Notations}}
\item\relax\sphinxstyleindexentry{Printing Parentheses}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:flag.Printing-Parentheses}}
\item\relax\sphinxstyleindexentry{Printing Primitive Projection Parameters}\sphinxstyleindexpageref{language/core/records:\detokenize{coq:flag.Printing-Primitive-Projection-Parameters}}
\item\relax\sphinxstyleindexentry{Printing Projections}\sphinxstyleindexpageref{language/core/records:\detokenize{coq:flag.Printing-Projections}}
\item\relax\sphinxstyleindexentry{Printing Raw Literals}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:flag.Printing-Raw-Literals}}
\item\relax\sphinxstyleindexentry{Printing Record}\sphinxstyleindexpageref{language/core/records:\detokenize{coq:table.Printing-Record}}
\item\relax\sphinxstyleindexentry{Printing Records}\sphinxstyleindexpageref{language/core/records:\detokenize{coq:flag.Printing-Records}}
\item\relax\sphinxstyleindexentry{Printing Synth}\sphinxstyleindexpageref{language/extensions/match:\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{addendum/universe-polymorphism:\detokenize{coq:flag.Printing-Universes}}
\item\relax\sphinxstyleindexentry{Printing Use Implicit Types}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:flag.Printing-Use-Implicit-Types}}
\item\relax\sphinxstyleindexentry{Printing Width}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:opt.Printing-Width}}
\item\relax\sphinxstyleindexentry{Printing Wildcard}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:flag.Printing-Wildcard}}
\item\relax\sphinxstyleindexentry{Private Polymorphic Universes}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:flag.Private-Polymorphic-Universes}}
\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}}
\item\relax\sphinxstyleindexentry{Program Mode}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:flag.Program-Mode}}
\indexspace
\bigletter{r}
\item\relax\sphinxstyleindexentry{Regular Subst Tactic}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:flag.Regular-Subst-Tactic}}
\item\relax\sphinxstyleindexentry{Reversible Pattern Implicit}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:flag.Reversible-Pattern-Implicit}}
\item\relax\sphinxstyleindexentry{Rewriting Schemes}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:flag.Rewriting-Schemes}}
\indexspace
\bigletter{s}
\item\relax\sphinxstyleindexentry{Search Blacklist}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:table.Search-Blacklist}}
\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/core/modules:\detokenize{coq:flag.Short-Module-Printing}}
\item\relax\sphinxstyleindexentry{Silent}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.Silent}}
\item\relax\sphinxstyleindexentry{Simplex}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:flag.Simplex}}
\item\relax\sphinxstyleindexentry{Solve Unification Constraints}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.Solve-Unification-Constraints}}
\item\relax\sphinxstyleindexentry{SsrHave NoTCResolution}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:flag.SsrHave-NoTCResolution}}
\item\relax\sphinxstyleindexentry{SsrIdents}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:flag.SsrIdents}}
\item\relax\sphinxstyleindexentry{SsrOldRewriteGoalsOrder}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:flag.SsrOldRewriteGoalsOrder}}
\item\relax\sphinxstyleindexentry{SsrRewrite}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:flag.SsrRewrite}}
\item\relax\sphinxstyleindexentry{Strict Implicit}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\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/extensions/implicit-arguments:\detokenize{coq:flag.Strongly-Strict-Implicit}}
\item\relax\sphinxstyleindexentry{Structural Injection}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:flag.Structural-Injection}}
\item\relax\sphinxstyleindexentry{Suggest Proof Using}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\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 Depth}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:opt.Typeclasses-Depth}}
\item\relax\sphinxstyleindexentry{Typeclasses Filtered Unification}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.Typeclasses-Filtered-Unification}}
\item\relax\sphinxstyleindexentry{Typeclasses Iterative Deepening}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.Typeclasses-Iterative-Deepening}}
\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{Uniform Inductive Parameters}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:flag.Uniform-Inductive-Parameters}}
\item\relax\sphinxstyleindexentry{Universal Lemma Under Conjunction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.Universal-Lemma-Under-Conjunction}}
\item\relax\sphinxstyleindexentry{Universe Checking}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.Universe-Checking}}
\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}{Gallina Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{b}
\item\relax\sphinxstyleindexentry{Bound on the ceiling function}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:thm.Bound-on-the-ceiling-function}}
\end{sphinxtheindex}
\renewcommand{\indexname}{Errors and Warnings Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{'}
\item\relax\sphinxstyleindexentry{'via' and 'abstract' cannot be used together}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.'via'-and-'abstract'-cannot-be-used-together}}
\indexspace
\bigletter{.}
\item\relax\sphinxstyleindexentry{... is not definitionally an identity function}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:warn....-is-not-definitionally-an-identity-function}}
\indexspace
\bigletter{a}
\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{Argument ‘name’ is a trailing implicit, so it can't be declared non maximal. Please use \{ \} instead of {[} {]}}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:exn.Argument-_u2018name_u2019-is-a-trailing-implicit,-so-it-can't-be-declared-non-maximal.-Please-use-_-_-instead-of-_-_}}
\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{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.Attempt-to-save-an-incomplete-proof}}
\item\relax\sphinxstyleindexentry{Automatically declaring ‘ident’ as template polymorphic}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:warn.Automatically-declaring-_u2018ident_u2019-as-template-polymorphic}}
\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{proofs/writing-proofs/equality:\detokenize{coq:exn.Bad-occurrence-number-of-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{Bad relevance}\sphinxstyleindexpageref{addendum/sprop:\detokenize{coq:warn.Bad-relevance}}
\item\relax\sphinxstyleindexentry{Bad ring structure}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.Bad-ring-structure}}
\item\relax\sphinxstyleindexentry{Brackets do not support multi\sphinxhyphen{}goal selectors}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.Brackets-do-not-support-multi-goal-selectors}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{Cannot build functional inversion principle}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:warn.Cannot-build-functional-inversion-principle}}
\item\relax\sphinxstyleindexentry{Cannot coerce ‘qualid’ to an evaluable reference}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:exn.Cannot-coerce-_u2018qualid_u2019-to-an-evaluable-reference}}
\item\relax\sphinxstyleindexentry{Cannot define graph for ‘ident’}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:warn.Cannot-define-graph-for-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Cannot define principle(s) for ‘ident’}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:warn.Cannot-define-principle(s)-for-_u2018ident_u2019}}
\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-_u2018term_u2019}}
\item\relax\sphinxstyleindexentry{Cannot find a declared ring structure over ‘term’}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.Cannot-find-a-declared-ring-structure-over-_u2018term_u2019}}
\item\relax\sphinxstyleindexentry{Cannot find a relation to rewrite}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Cannot-find-a-relation-to-rewrite}}
\item\relax\sphinxstyleindexentry{Cannot find any non\sphinxhyphen{}recursive equality over ‘ident’}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Cannot-find-any-non-recursive-equality-over-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Cannot find induction information on ‘qualid’}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:exn.Cannot-find-induction-information-on-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{Cannot find inversion information for hypothesis ‘ident’}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:exn.Cannot-find-inversion-information-for-hypothesis-_u2018ident_u2019}}
\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-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{Cannot handle mutually (co)inductive records}\sphinxstyleindexpageref{language/core/records:\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/extensions/implicit-arguments:\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 interpret in ‘scope\_name’ because ‘qualid’ could not be found in the current environment}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Cannot-interpret-in-_u2018scope_name_u2019-because-_u2018qualid_u2019-could-not-be-found-in-the-current-environment}}
\item\relax\sphinxstyleindexentry{Cannot interpret this number as a value of type ‘type’}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Cannot-interpret-this-number-as-a-value-of-type-_u2018type_u2019}}
\item\relax\sphinxstyleindexentry{Cannot interpret this string as a value of type ‘type’}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Cannot-interpret-this-string-as-a-value-of-type-_u2018type_u2019}}
\item\relax\sphinxstyleindexentry{Cannot load ‘qualid’: no physical path bound to ‘dirpath’}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.Cannot-load-_u2018qualid_u2019:-no-physical-path-bound-to-_u2018dirpath_u2019}}
\item\relax\sphinxstyleindexentry{Cannot move ‘ident’ after ‘ident’: it depends on ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.Cannot-move-_u2018ident_u2019-after-_u2018ident_u2019:-it-depends-on-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Cannot move ‘ident’ after ‘ident’: it occurs in the type of ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.Cannot-move-_u2018ident_u2019-after-_u2018ident_u2019:-it-occurs-in-the-type-of-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Cannot recognize a boolean equality}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\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-_u2018class_u2019-as-a-source-class-of-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{Cannot turn {[}inductive|constructor{]} into an evaluable reference}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Cannot-turn-_inductive|constructor_-into-an-evaluable-reference}}
\item\relax\sphinxstyleindexentry{Cannot use mutual definition with well\sphinxhyphen{}founded recursion or measure}\sphinxstyleindexpageref{using/libraries/funind:\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.Can_u2019t-find-file-_u2018ident_u2019-on-loadpath}}
\item\relax\sphinxstyleindexentry{Casts are not supported in this pattern}\sphinxstyleindexpageref{language/core/variants:\detokenize{coq:exn.Casts-are-not-supported-in-this-pattern}}
\item\relax\sphinxstyleindexentry{Compiled library ‘ident’.vo makes inconsistent assumptions over library ‘qualid’}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.Compiled-library-_u2018ident_u2019.vo-makes-inconsistent-assumptions-over-library-_u2018qualid_u2019}}
\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}}
\item\relax\sphinxstyleindexentry{Declaring arbitrary terms as hints is fragile; it is recommended to declare a toplevel constant instead}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:warn.Declaring-arbitrary-terms-as-hints-is-fragile;-it-is-recommended-to-declare-a-toplevel-constant-instead}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{Either there is a type incompatibility or the problem involves dependencies}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:exn.Either-there-is-a-type-incompatibility-or-the-problem-involves-dependencies}}
\item\relax\sphinxstyleindexentry{Expression does not evaluate to a tactic}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.Expression-does-not-evaluate-to-a-tactic}}
\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:-_u2018string_u2019}}
\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{Flag 'rename' expected to rename ‘name’ into ‘name’}\sphinxstyleindexpageref{language/extensions/arguments-command:\detokenize{coq:exn.Flag-'rename'-expected-to-rename-_u2018name_u2019-into-_u2018name_u2019}}
\item\relax\sphinxstyleindexentry{Found a constructor of inductive type term while a constructor of term is expected}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:exn.Found-a-constructor-of-inductive-type-term-while-a-constructor-of-term-is-expected}}
\item\relax\sphinxstyleindexentry{Found an "at" clause without "with" clause}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Found-an-"at"-clause-without-"with"-clause}}
\item\relax\sphinxstyleindexentry{Found no subterm matching ‘term’ in the current goal}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Found-no-subterm-matching-_u2018term_u2019-in-the-current-goal}}
\item\relax\sphinxstyleindexentry{Found no subterm matching ‘term’ in ‘ident’}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Found-no-subterm-matching-_u2018term_u2019-in-_u2018ident_u2019}}
\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{proofs/writing-proofs/reasoning-inductives:\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{proofs/automatic-tactics/logic:\detokenize{coq:exn.Goal-is-solvable-by-congruence-but-some-arguments-are-missing.-Try-congruence-with-_u2018term_u2019_u2026_u2018term_u2019,-replacing-metavariables-by-arbitrary-terms}}
\indexspace
\bigletter{h}
\item\relax\sphinxstyleindexentry{Hypothesis ‘ident’ must contain at least one Function}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:exn.Hypothesis-_u2018ident_u2019-must-contain-at-least-one-Function}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{I don’t know how to handle dependent equality}\sphinxstyleindexpageref{proofs/automatic-tactics/logic:\detokenize{coq:exn.I-don_u2019t-know-how-to-handle-dependent-equality}}
\item\relax\sphinxstyleindexentry{Ignored instance declaration for “‘ident’”: “‘term’” is not a class}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:warn.Ignored-instance-declaration-for-_u201c_u2018ident_u2019_u201d:-_u201c_u2018term_u2019_u201d-is-not-a-class}}
\item\relax\sphinxstyleindexentry{Ignoring implicit binder declaration in unexpected position}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:warn.Ignoring-implicit-binder-declaration-in-unexpected-position}}
\item\relax\sphinxstyleindexentry{Ill\sphinxhyphen{}formed recursive definition}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:exn.Ill-formed-recursive-definition}}
\item\relax\sphinxstyleindexentry{Ill\sphinxhyphen{}formed template inductive declaration: not polymorphic on any universe}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:exn.Ill-formed-template-inductive-declaration:-not-polymorphic-on-any-universe}}
\item\relax\sphinxstyleindexentry{Incorrect number of tactics (expected N tactics, was given M)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:exn.Incorrect-number-of-tactics-(expected-N-tactics,-was-given-M)}}
\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{Last block to end has name ‘ident’}\sphinxstyleindexpageref{language/core/sections:\detokenize{coq:exn.Last-block-to-end-has-name-_u2018ident_u2019}}
\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{Ltac Profiler encountered an invalid stack (no self node). This can happen if you reset the profile during tactic execution}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:warn.Ltac-Profiler-encountered-an-invalid-stack-(no-self-node).-This-can-happen-if-you-reset-the-profile-during-tactic-execution}}
\item\relax\sphinxstyleindexentry{Ltac2 alias ‘qualid’ is deprecated since ‘string’. ‘string’}\sphinxstyleindexpageref{using/libraries/writing:\detokenize{coq:warn.Ltac2-alias-_u2018qualid_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}
\item\relax\sphinxstyleindexentry{Ltac2 definition ‘qualid’ is deprecated since ‘string’. ‘string’}\sphinxstyleindexpageref{using/libraries/writing:\detokenize{coq:warn.Ltac2-definition-_u2018qualid_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}
\item\relax\sphinxstyleindexentry{Ltac2 notation ‘ltac2\_scope’…‘ltac2\_scope’ is deprecated since ‘string’. ‘string’}\sphinxstyleindexpageref{using/libraries/writing:\detokenize{coq:warn.Ltac2-notation-_u2018ltac2_scope_u2019_u2026_u2018ltac2_scope_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{Making shadowed name of implicit argument accessible by position}\sphinxstyleindexpageref{language/extensions/implicit-arguments:\detokenize{coq:warn.Making-shadowed-name-of-implicit-argument-accessible-by-position}}
\item\relax\sphinxstyleindexentry{Missing mapping for constructor ‘qualid’}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Missing-mapping-for-constructor-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{Module/section ‘qualid’ not found}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.Module/section-_u2018qualid_u2019-not-found}}
\item\relax\sphinxstyleindexentry{Multiple 'via' options}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Multiple-'via'-options}}
\item\relax\sphinxstyleindexentry{Multiple 'warning after' or 'abstract after' options}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Multiple-'warning-after'-or-'abstract-after'-options}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{Nested proofs are discouraged and not allowed by default. This error probably means that you forgot to close the last "Proof." with "Qed." or "Defined.". If you really intended to use nested proofs, you can do so by turning the "Nested Proofs Allowed" flag on}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:exn.Nested-proofs-are-discouraged-and-not-allowed-by-default.-This-error-probably-means-that-you-forgot-to-close-the-last-"Proof."-with-"Qed."-or-"Defined.".-If-you-really-intended-to-use-nested-proofs,-you-can-do-so-by-turning-the-"Nested-Proofs-Allowed"-flag-on}}
\item\relax\sphinxstyleindexentry{New coercion path ... is ambiguous with existing ...}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:warn.New-coercion-path-...-is-ambiguous-with-existing-...}}
\item\relax\sphinxstyleindexentry{No applicable tactic}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.No-applicable-tactic}}
\item\relax\sphinxstyleindexentry{No argument name ‘ident’}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:exn.No-argument-name-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{No discriminable equalities}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.No-focused-proof}}
\item\relax\sphinxstyleindexentry{No focused proof (No proof\sphinxhyphen{}editing in progress)}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.No-focused-proof-(No-proof-editing-in-progress)}}
\item\relax\sphinxstyleindexentry{No focused proof to restart}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.No-focused-proof-to-restart}}
\item\relax\sphinxstyleindexentry{No head constant to reduce}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.No-primitive-equality-found}}
\item\relax\sphinxstyleindexentry{No product even after head\sphinxhyphen{}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{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.No-such-goal}}
\item\relax\sphinxstyleindexentry{No such goal (‘ident’)}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.No-such-goal-(_u2018ident_u2019)}}
\item\relax\sphinxstyleindexentry{No such goal (‘natural’)}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.No-such-goal-(_u2018natural_u2019)}}
\item\relax\sphinxstyleindexentry{No such goal. (fail)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.No-such-goal.-(fail)}}
\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{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.No-such-goal.-Focus-next-goal-with-bullet-_u2018bullet_u2019}}
\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:-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{No such label ‘ident’}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:exn.No-such-label-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Non exhaustive pattern matching}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:exn.Non-exhaustive-pattern-matching}}
\item\relax\sphinxstyleindexentry{Non strictly positive occurrence of ‘ident’ in ‘type’}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:exn.Non-strictly-positive-occurrence-of-_u2018ident_u2019-in-_u2018type_u2019}}
\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Not-a-discriminable-equality}}
\item\relax\sphinxstyleindexentry{Not a primitive equality}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Not-a-primitive-equality}}
\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Not-an-inductive-goal-with-1-constructor}}
\item\relax\sphinxstyleindexentry{Not an inductive goal with 2 constructors}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Not-an-inductive-goal-with-2-constructors}}
\item\relax\sphinxstyleindexentry{Not an inductive product}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Not-an-inductive-product}}
\item\relax\sphinxstyleindexentry{Not convertible}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Not-convertible}}
\item\relax\sphinxstyleindexentry{Not enough constructors}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Not-enough-constructors}}
\item\relax\sphinxstyleindexentry{Not equal}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.Not-equal}}
\item\relax\sphinxstyleindexentry{Not equal (due to universes)}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.Not-equal-(due-to-universes)}}
\item\relax\sphinxstyleindexentry{Not the right number of induction arguments}\sphinxstyleindexpageref{using/libraries/funind:\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{Notation levels must range between 0 and 6}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:exn.Notation-levels-must-range-between-0-and-6}}
\item\relax\sphinxstyleindexentry{Notation ‘string’ is deprecated since ‘string’. ‘string’}\sphinxstyleindexpageref{using/libraries/writing:\detokenize{coq:warn.Notation-_u2018string_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}
\item\relax\sphinxstyleindexentry{Nothing to do, it is an equality between convertible terms}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Nothing-to-do,-it-is-an-equality-between-convertible-terms}}
\item\relax\sphinxstyleindexentry{Nothing to inject}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\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{overflow in int63 literal ‘bigint’}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.overflow-in-int63-literal-_u2018bigint_u2019}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{Polymorphic universe constraints can only be declared inside sections, use Monomorphic Constraint instead}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:exn.Polymorphic-universe-constraints-can-only-be-declared-inside-sections,-use-Monomorphic-Constraint-instead}}
\item\relax\sphinxstyleindexentry{Polymorphic universes can only be declared inside sections, use Monomorphic Universe instead}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:exn.Polymorphic-universes-can-only-be-declared-inside-sections,-use-Monomorphic-Universe-instead}}
\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{r}
\item\relax\sphinxstyleindexentry{Records declared with the keyword Record or Structure cannot be recursive}\sphinxstyleindexpageref{language/core/records:\detokenize{coq:exn.Records-declared-with-the-keyword-Record-or-Structure-cannot-be-recursive}}
\item\relax\sphinxstyleindexentry{Refine passed ill\sphinxhyphen{}formed term}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.Refine-passed-ill-formed-term}}
\item\relax\sphinxstyleindexentry{Require inside a module is deprecated and strongly discouraged. You can Require a module at toplevel and optionally Import it inside another one}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:warn.Require-inside-a-module-is-deprecated-and-strongly-discouraged.-You-can-Require-a-module-at-toplevel-and-optionally-Import-it-inside-another-one}}
\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{Section variable ‘ident’ occurs implicitly in global declaration ‘qualid’ present in hypothesis ‘ident’}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Section-variable-_u2018ident_u2019-occurs-implicitly-in-global-declaration-_u2018qualid_u2019-present-in-hypothesis-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Section variable ‘ident’ occurs implicitly in global declaration ‘qualid’ present in the conclusion}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Section-variable-_u2018ident_u2019-occurs-implicitly-in-global-declaration-_u2018qualid_u2019-present-in-the-conclusion}}
\item\relax\sphinxstyleindexentry{Signature components for label ‘ident’ do not match}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:exn.Signature-components-for-label-_u2018ident_u2019-do-not-match}}
\item\relax\sphinxstyleindexentry{SProp is disallowed because the "Allow StrictProp" flag is off}\sphinxstyleindexpageref{addendum/sprop:\detokenize{coq:exn.SProp-is-disallowed-because-the-"Allow-StrictProp"-flag-is-off}}
\item\relax\sphinxstyleindexentry{SSReflect: cannot obtain new equations out of ...}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:warn.SSReflect:-cannot-obtain-new-equations-out-of-...}}
\item\relax\sphinxstyleindexentry{Stack overflow or segmentation fault happens when working with large numbers in ‘type’ (threshold may vary depending on your system limits and on the command executed)}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:warn.Stack-overflow-or-segmentation-fault-happens-when-working-with-large-numbers-in-_u2018type_u2019-(threshold-may-vary-depending-on-your-system-limits-and-on-the-command-executed)}}
\item\relax\sphinxstyleindexentry{Statement without assumptions}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.Statement-without-assumptions}}
\item\relax\sphinxstyleindexentry{Syntax error: {[}prim:reference{]} expected after 'Notation' (in {[}vernac:command{]})}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Syntax-error:-_prim:reference_-expected-after-'Notation'-(in-_vernac:command_)}}
\item\relax\sphinxstyleindexentry{Syntax error: {[}prim:reference{]} expected after {[}prim:reference{]} (in {[}vernac:command{]})}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Syntax-error:-_prim:reference_-expected-after-_prim:reference_-(in-_vernac:command_)}}
\indexspace
\bigletter{t}
\item\relax\sphinxstyleindexentry{Tactic failure}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.Tactic-failure}}
\item\relax\sphinxstyleindexentry{Tactic failure (level ‘natural’)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.Tactic-failure-(level-_u2018natural_u2019)}}
\item\relax\sphinxstyleindexentry{Tactic failure: <tactic closure> fails}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.Tactic-failure:-<tactic-closure>-fails}}
\item\relax\sphinxstyleindexentry{Tactic failure: <tactic closure> succeeds}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.Tactic-failure:-<tactic-closure>-succeeds}}
\item\relax\sphinxstyleindexentry{Tactic failure: Setoid library not loaded}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Tactic-failure:-Setoid-library-not-loaded}}
\item\relax\sphinxstyleindexentry{Tactic generated a subgoal identical to the original goal}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Tactic-generated-a-subgoal-identical-to-the-original-goal}}
\item\relax\sphinxstyleindexentry{Tactic Notation ‘qualid’ is deprecated since ‘string’. ‘string’}\sphinxstyleindexpageref{using/libraries/writing:\detokenize{coq:warn.Tactic-Notation-_u2018qualid_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}
\item\relax\sphinxstyleindexentry{Tactic ‘qualid’ is deprecated since ‘string’. ‘string’}\sphinxstyleindexpageref{using/libraries/writing:\detokenize{coq:warn.Tactic-_u2018qualid_u2019-is-deprecated-since-_u2018string_u2019.-_u2018string_u2019}}
\item\relax\sphinxstyleindexentry{template and polymorphism not compatible}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:exn.template-and-polymorphism-not-compatible}}
\item\relax\sphinxstyleindexentry{Terms do not have convertible types}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.Terms-do-not-have-convertible-types}}
\item\relax\sphinxstyleindexentry{The "at" syntax isn't available yet for the autorewrite tactic}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:exn.The-"at"-syntax-isn't-available-yet-for-the-autorewrite-tactic}}
\item\relax\sphinxstyleindexentry{The \& modifier may only occur once}\sphinxstyleindexpageref{language/extensions/arguments-command:\detokenize{coq:exn.The-_-modifier-may-only-occur-once}}
\item\relax\sphinxstyleindexentry{The 'abstract after' directive has no effect when the parsing function (‘qualid’) targets an option type}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:warn.The-'abstract-after'-directive-has-no-effect-when-the-parsing-function-(_u2018qualid_u2019)-targets-an-option-type}}
\item\relax\sphinxstyleindexentry{The 'clear implicits' flag must be omitted if implicit annotations are given}\sphinxstyleindexpageref{language/extensions/arguments-command:\detokenize{coq:exn.The-'clear-implicits'-flag-must-be-omitted-if-implicit-annotations-are-given}}
\item\relax\sphinxstyleindexentry{The 'default implicits' flag is incompatible with implicit annotations}\sphinxstyleindexpageref{language/extensions/arguments-command:\detokenize{coq:exn.The-'default-implicits'-flag-is-incompatible-with-implicit-annotations}}
\item\relax\sphinxstyleindexentry{The / modifier may only occur once}\sphinxstyleindexpageref{language/extensions/arguments-command:\detokenize{coq:exn.The-/-modifier-may-only-occur-once}}
\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 of ‘type’ is not valid; it must be built from ‘ident’}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:exn.The-conclusion-of-_u2018type_u2019-is-not-valid;-it-must-be-built-from-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{The constant ‘number’ is not a binary64 floating\sphinxhyphen{}point value. A closest value ‘number’ will be used and unambiguously printed ‘number’. {[}inexact\sphinxhyphen{}float,parsing{]}}\sphinxstyleindexpageref{language/coq-library:\detokenize{coq:warn.The-constant-_u2018number_u2019-is-not-a-binary64-floating-point-value.-A-closest-value-_u2018number_u2019-will-be-used-and-unambiguously-printed-_u2018number_u2019.-_inexact-float,parsing_}}
\item\relax\sphinxstyleindexentry{The constructor ‘ident’ expects ‘natural’ arguments}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:exn.The-constructor-_u2018ident_u2019-expects-_u2018natural_u2019-arguments}}
\item\relax\sphinxstyleindexentry{The cumulative attribute can only be used in a polymorphic context}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:exn.The-cumulative-attribute-can-only-be-used-in-a-polymorphic-context}}
\item\relax\sphinxstyleindexentry{The elimination predicate term should be of arity ‘natural’ (for non dependent case) or ‘natural’ (for dependent case)}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:exn.The-elimination-predicate-term-should-be-of-arity-_u2018natural_u2019-(for-non-dependent-case)-or-_u2018natural_u2019-(for-dependent-case)}}
\item\relax\sphinxstyleindexentry{The field ‘ident’ is missing in ‘qualid’}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:exn.The-field-_u2018ident_u2019-is-missing-in-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{The file ‘ident’.vo contains library ‘qualid’ and not library ‘qualid’}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.The-file-_u2018ident_u2019.vo-contains-library-_u2018qualid_u2019-and-not-library-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{The recursive argument must be specified}\sphinxstyleindexpageref{using/libraries/funind:\detokenize{coq:exn.The-recursive-argument-must-be-specified}}
\item\relax\sphinxstyleindexentry{The reference is not unfoldable}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.The-reference-is-not-unfoldable}}
\item\relax\sphinxstyleindexentry{The reference X was not found in the current environment}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:exn.The-reference-X-was-not-found-in-the-current-environment}}
\item\relax\sphinxstyleindexentry{The reference ‘qualid’ was not found in the current environment}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.The-reference-_u2018qualid_u2019-was-not-found-in-the-current-environment}}
\item\relax\sphinxstyleindexentry{The relation ‘ident’ is not a declared reflexive relation. Maybe you need to require the Coq.Classes.RelationClasses library}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.The-relation-_u2018ident_u2019-is-not-a-declared-reflexive-relation.-Maybe-you-need-to-require-the-Coq.Classes.RelationClasses-library}}
\item\relax\sphinxstyleindexentry{The relation ‘ident’ is not a declared symmetric relation. Maybe you need to require the Coq.Classes.RelationClasses library}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.The-relation-_u2018ident_u2019-is-not-a-declared-symmetric-relation.-Maybe-you-need-to-require-the-Coq.Classes.RelationClasses-library}}
\item\relax\sphinxstyleindexentry{The relation ‘ident’ is not a declared transitive relation. Maybe you need to require the Coq.Classes.RelationClasses library}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn.The-relation-_u2018ident_u2019-is-not-a-declared-transitive-relation.-Maybe-you-need-to-require-the-Coq.Classes.RelationClasses-library}}
\item\relax\sphinxstyleindexentry{The term ‘term’ has type ‘type’ which should be Set, Prop or Type}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:exn.The-term-_u2018term_u2019-has-type-_u2018type_u2019-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/core/definitions:\detokenize{coq:exn.The-term-_u2018term_u2019-has-type-_u2018type_u2019-while-it-is-expected-to-have-type-_u2018type_u2019'}}
\item\relax\sphinxstyleindexentry{The type ‘ident’ must be registered before this construction can be typechecked}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.The-type-_u2018ident_u2019-must-be-registered-before-this-construction-can-be-typechecked}}
\item\relax\sphinxstyleindexentry{The variable ident is bound several times in pattern term}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:exn.The-variable-ident-is-bound-several-times-in-pattern-term}}
\item\relax\sphinxstyleindexentry{The variable ‘ident’ is already defined}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.The-variable-_u2018ident_u2019-is-already-defined}}
\item\relax\sphinxstyleindexentry{The ‘natural’ th argument of ‘ident’ must be ‘ident’ in ‘type’}\sphinxstyleindexpageref{language/core/variants:\detokenize{coq:exn.The-_u2018natural_u2019-th-argument-of-_u2018ident_u2019-must-be-_u2018ident_u2019-in-_u2018type_u2019}}
\item\relax\sphinxstyleindexentry{There is already an Ltac named ‘qualid’}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.There-is-already-an-Ltac-named-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{There is no flag or option with this name: "‘setting\_name’"}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:warn.There-is-no-flag-or-option-with-this-name:-"_u2018setting_name_u2019"}}
\item\relax\sphinxstyleindexentry{There is no flag, option or table with this name: "‘setting\_name’"}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:exn.There-is-no-flag,-option-or-table-with-this-name:-"_u2018setting_name_u2019"}}
\item\relax\sphinxstyleindexentry{There is no Ltac named ‘qualid’}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.There-is-no-Ltac-named-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{There is no qualid\sphinxhyphen{}valued table with this name: "‘setting\_name’"}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:exn.There-is-no-qualid-valued-table-with-this-name:-"_u2018setting_name_u2019"}}
\item\relax\sphinxstyleindexentry{There is no string\sphinxhyphen{}valued table with this name: "‘setting\_name’"}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:exn.There-is-no-string-valued-table-with-this-name:-"_u2018setting_name_u2019"}}
\item\relax\sphinxstyleindexentry{There is nothing to end}\sphinxstyleindexpageref{language/core/sections:\detokenize{coq:exn.There-is-nothing-to-end}}
\item\relax\sphinxstyleindexentry{This command does not support this attribute}\sphinxstyleindexpageref{language/core/basic:\detokenize{coq:warn.This-command-does-not-support-this-attribute}}
\item\relax\sphinxstyleindexentry{This command is just asserting the names of arguments of ‘qualid’. If this is what you want, add ': assert' to silence the warning. If you want to clear implicit arguments, add ': clear implicits'. If you want to clear notation scopes, add ': clear scopes'}\sphinxstyleindexpageref{language/extensions/arguments-command:\detokenize{coq:warn.This-command-is-just-asserting-the-names-of-arguments-of-_u2018qualid_u2019.-If-this-is-what-you-want,-add-':-assert'-to-silence-the-warning.-If-you-want-to-clear-implicit-arguments,-add-':-clear-implicits'.-If-you-want-to-clear-notation-scopes,-add-':-clear-scopes'}}
\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{proofs/writing-proofs/proof-mode:\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{To avoid stack overflow, large numbers in ‘type’ are interpreted as applications of ‘qualid’}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:warn.To-avoid-stack-overflow,-large-numbers-in-_u2018type_u2019-are-interpreted-as-applications-of-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{To rename arguments the 'rename' flag must be specified}\sphinxstyleindexpageref{language/extensions/arguments-command:\detokenize{coq:exn.To-rename-arguments-the-'rename'-flag-must-be-specified}}
\item\relax\sphinxstyleindexentry{Trying to mask the absolute name ‘qualid’!}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:warn.Trying-to-mask-the-absolute-name-_u2018qualid_u2019!}}
\item\relax\sphinxstyleindexentry{Type of ‘ident’ is not an equality of recognized Σ types: expected one of sig sig2 sigT sigT2 sigT2 ex or ex2 but got ‘term’}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Type-of-_u2018ident_u2019-is-not-an-equality-of-recognized-_u03a3-types:-expected-one-of-sig-sig2-sigT-sigT2-sigT2-ex-or-ex2-but-got-_u2018term_u2019}}
\item\relax\sphinxstyleindexentry{Type of ‘qualid’ seems incompatible with the type of ‘qualid’. Expected type is: ‘type’ instead of ‘type’. This might yield ill typed terms when using the notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:warn.Type-of-_u2018qualid_u2019-seems-incompatible-with-the-type-of-_u2018qualid_u2019.-Expected-type-is:-_u2018type_u2019-instead-of-_u2018type_u2019.-This-might-yield-ill-typed-terms-when-using-the-notation}}
\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{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn.Unable-to-find-an-instance-for-the-variables-_u2018ident_u2019-...-_u2018ident_u2019}}
\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-_u2018ident_u2019_u2026_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Unable to infer a match predicate}\sphinxstyleindexpageref{language/extensions/match:\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 ‘term’ with ‘term’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.Unable-to-unify-_u2018term_u2019-with-_u2018term_u2019}}
\item\relax\sphinxstyleindexentry{Unbound {[}value|constructor{]} X}\sphinxstyleindexpageref{proof-engine/ltac2:\detokenize{coq:exn.Unbound-_value|constructor_-X}}
\item\relax\sphinxstyleindexentry{Unbound context identifier ‘ident’}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.Unbound-context-identifier-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Undeclared universe ‘ident’}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:exn.Undeclared-universe-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{Unexpected non\sphinxhyphen{}option term ‘term’ while parsing a number notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Unexpected-non-option-term-_u2018term_u2019-while-parsing-a-number-notation}}
\item\relax\sphinxstyleindexentry{Unexpected non\sphinxhyphen{}option term ‘term’ while parsing a string notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Unexpected-non-option-term-_u2018term_u2019-while-parsing-a-string-notation}}
\item\relax\sphinxstyleindexentry{Unexpected term ‘term’ while parsing a number notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Unexpected-term-_u2018term_u2019-while-parsing-a-number-notation}}
\item\relax\sphinxstyleindexentry{Unexpected term ‘term’ while parsing a string notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn.Unexpected-term-_u2018term_u2019-while-parsing-a-string-notation}}
\item\relax\sphinxstyleindexentry{Universe inconsistency}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:exn.Universe-inconsistency}}
\item\relax\sphinxstyleindexentry{Universe instance should have length ‘natural’}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.Universe-instance-should-have-length-_u2018natural_u2019}}
\item\relax\sphinxstyleindexentry{Unknown inductive type}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.Unknown-inductive-type}}
\item\relax\sphinxstyleindexentry{Unused variable ‘ident’ catches more than one case}\sphinxstyleindexpageref{language/extensions/match:\detokenize{coq:warn.Unused-variable-_u2018ident_u2019-catches-more-than-one-case}}
\item\relax\sphinxstyleindexentry{Use of ‘string’ Notation is deprecated as it is inconsistent with pattern syntax}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:warn.Use-of-_u2018string_u2019-Notation-is-deprecated-as-it-is-inconsistent-with-pattern-syntax}}
\indexspace
\bigletter{v}
\item\relax\sphinxstyleindexentry{Variable ‘ident’ is already declared}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.Variable-_u2018ident_u2019-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-_u2018term_u2019-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{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.Wrong-bullet-_u2018bullet_u2019:-Bullet-_u2018bullet_u2019-is-mandatory-here}}
\item\relax\sphinxstyleindexentry{Wrong bullet ‘bullet’: Current bullet ‘bullet’ is not finished}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:exn.Wrong-bullet-_u2018bullet_u2019:-Current-bullet-_u2018bullet_u2019-is-not-finished}}
\indexspace
\bigletter{y}
\item\relax\sphinxstyleindexentry{You should use the “Proof using {[}...{]}.” syntax instead of “Proof.” to enable skipping this proof which is located inside a section. Give as argument to “Proof using” the list of section variables that are not needed to typecheck the statement but that are required by the proof}\sphinxstyleindexpageref{practical-tools/coq-commands:\detokenize{coq:warn.You-should-use-the-_u201cProof-using-_..._._u201d-syntax-instead-of-_u201cProof._u201d-to-enable-skipping-this-proof-which-is-located-inside-a-section.-Give-as-argument-to-_u201cProof-using_u201d-the-list-of-section-variables-that-are-not-needed-to-typecheck-the-statement-but-that-are-required-by-the-proof}}
\indexspace
\bigletter{‘}
\item\relax\sphinxstyleindexentry{‘class’ must be a transparent constant}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn._u2018class_u2019-must-be-a-transparent-constant}}
\item\relax\sphinxstyleindexentry{‘ident’ already exists. (Axiom)}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:exn._u2018ident_u2019-already-exists.-(Axiom)}}
\item\relax\sphinxstyleindexentry{‘ident’ already exists. (Definition)}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:exn._u2018ident_u2019-already-exists.-(Definition)}}
\item\relax\sphinxstyleindexentry{‘ident’ already exists. (Theorem)}\sphinxstyleindexpageref{language/core/definitions:\detokenize{coq:exn._u2018ident_u2019-already-exists.-(Theorem)}}
\item\relax\sphinxstyleindexentry{‘ident’ cannot be defined}\sphinxstyleindexpageref{language/core/records:\detokenize{coq:warn._u2018ident_u2019-cannot-be-defined}}
\item\relax\sphinxstyleindexentry{‘ident’ is already declared as a typeclass}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:warn._u2018ident_u2019-is-already-declared-as-a-typeclass}}
\item\relax\sphinxstyleindexentry{‘ident’ is already used}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn._u2018ident_u2019-is-already-used}}
\item\relax\sphinxstyleindexentry{‘ident’ is declared as a local axiom}\sphinxstyleindexpageref{language/core/assumptions:\detokenize{coq:warn._u2018ident_u2019-is-declared-as-a-local-axiom}}
\item\relax\sphinxstyleindexentry{‘ident’ is not a local definition}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn._u2018ident_u2019-is-not-a-local-definition}}
\item\relax\sphinxstyleindexentry{‘ident’ is not an equality of Σ types}\sphinxstyleindexpageref{proofs/writing-proofs/reasoning-inductives:\detokenize{coq:exn._u2018ident_u2019-is-not-an-equality-of-_u03a3-types}}
\item\relax\sphinxstyleindexentry{‘ident’ is opaque}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn._u2018ident_u2019-is-opaque}}
\item\relax\sphinxstyleindexentry{‘ident’ is used in conclusion}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn._u2018ident_u2019-is-used-in-conclusion}}
\item\relax\sphinxstyleindexentry{‘ident’ is used in hypothesis ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn._u2018ident_u2019-is-used-in-hypothesis-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{‘ident’ is used in the conclusion}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn._u2018ident_u2019-is-used-in-the-conclusion}}
\item\relax\sphinxstyleindexentry{‘ident’ is used in the hypothesis ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn._u2018ident_u2019-is-used-in-the-hypothesis-_u2018ident_u2019}}
\item\relax\sphinxstyleindexentry{‘ident’: no such entry}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn._u2018ident_u2019:-no-such-entry}}
\item\relax\sphinxstyleindexentry{‘qualid’ cannot be used as a hint}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:exn._u2018qualid_u2019-cannot-be-used-as-a-hint}}
\item\relax\sphinxstyleindexentry{‘qualid’ does not occur}\sphinxstyleindexpageref{proofs/writing-proofs/equality:\detokenize{coq:exn._u2018qualid_u2019-does-not-occur}}
\item\relax\sphinxstyleindexentry{‘qualid’ does not respect the uniform inheritance condition}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:warn._u2018qualid_u2019-does-not-respect-the-uniform-inheritance-condition}}
\item\relax\sphinxstyleindexentry{‘qualid’ is already a coercion}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn._u2018qualid_u2019-is-already-a-coercion}}
\item\relax\sphinxstyleindexentry{‘qualid’ is bound to a notation that does not denote a reference}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn._u2018qualid_u2019-is-bound-to-a-notation-that-does-not-denote-a-reference}}
\item\relax\sphinxstyleindexentry{‘qualid’ is not a function}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn._u2018qualid_u2019-is-not-a-function}}
\item\relax\sphinxstyleindexentry{‘qualid’ is not a module}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:exn._u2018qualid_u2019-is-not-a-module}}
\item\relax\sphinxstyleindexentry{‘qualid’ is not an inductive type}\sphinxstyleindexpageref{proofs/automatic-tactics/auto:\detokenize{coq:exn._u2018qualid_u2019-is-not-an-inductive-type}}
\item\relax\sphinxstyleindexentry{‘qualid’ not a defined object}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn._u2018qualid_u2019-not-a-defined-object}}
\item\relax\sphinxstyleindexentry{‘qualid’ not declared}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn._u2018qualid_u2019-not-declared}}
\item\relax\sphinxstyleindexentry{‘qualid’ should go from Byte.byte or (list Byte.byte) to ‘type’ or (option ‘type’)}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn._u2018qualid_u2019-should-go-from-Byte.byte-or-(list-Byte.byte)-to-_u2018type_u2019-or-(option-_u2018type_u2019)}}
\item\relax\sphinxstyleindexentry{‘qualid’ should go from Number.int to ‘type’ or (option ‘type’). Instead of Number.int, the types Number.uint or Z or PrimInt63.pos\_neg\_int63 or Number.number could be used (you may need to require BinNums or Number or PrimInt63 first)}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn._u2018qualid_u2019-should-go-from-Number.int-to-_u2018type_u2019-or-(option-_u2018type_u2019).-Instead-of-Number.int,-the-types-Number.uint-or-Z-or-PrimInt63.pos_neg_int63-or-Number.number-could-be-used-(you-may-need-to-require-BinNums-or-Number-or-PrimInt63-first)}}
\item\relax\sphinxstyleindexentry{‘qualid’ should go from ‘type’ to Byte.byte or (option Byte.byte) or (list Byte.byte) or (option (list Byte.byte))}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn._u2018qualid_u2019-should-go-from-_u2018type_u2019-to-Byte.byte-or-(option-Byte.byte)-or-(list-Byte.byte)-or-(option-(list-Byte.byte))}}
\item\relax\sphinxstyleindexentry{‘qualid’ should go from ‘type’ to Number.int or (option Number.int). Instead of Number.int, the types Number.uint or Z or PrimInt63.pos\_neg\_int63 or Number.number could be used (you may need to require BinNums or Number or PrimInt63 first)}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn._u2018qualid_u2019-should-go-from-_u2018type_u2019-to-Number.int-or-(option-Number.int).-Instead-of-Number.int,-the-types-Number.uint-or-Z-or-PrimInt63.pos_neg_int63-or-Number.number-could-be-used-(you-may-need-to-require-BinNums-or-Number-or-PrimInt63-first)}}
\item\relax\sphinxstyleindexentry{‘qualid’ was already mapped to ‘qualid’ and cannot be remapped to ‘qualid’}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn._u2018qualid_u2019-was-already-mapped-to-_u2018qualid_u2019-and-cannot-be-remapped-to-_u2018qualid_u2019}}
\item\relax\sphinxstyleindexentry{‘type’ is not an inductive type}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:exn._u2018type_u2019-is-not-an-inductive-type}}
\item\relax\sphinxstyleindexentry{‘type’ was already mapped to ‘type’, mapping it also to ‘type’ might yield ill typed terms when using the notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:warn._u2018type_u2019-was-already-mapped-to-_u2018type_u2019,-mapping-it-also-to-_u2018type_u2019-might-yield-ill-typed-terms-when-using-the-notation}}
\end{sphinxtheindex}
\renewcommand{\indexname}{Attribute Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{b}
\item\relax\sphinxstyleindexentry{bypass\_check(guard)}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:attr.bypass_check(guard)}}
\item\relax\sphinxstyleindexentry{bypass\_check(positivity)}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:attr.bypass_check(positivity)}}
\item\relax\sphinxstyleindexentry{bypass\_check(universes)}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:attr.bypass_check(universes)}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{canonical}\sphinxstyleindexpageref{language/extensions/canonical:\detokenize{coq:attr.canonical}}
\item\relax\sphinxstyleindexentry{Cumulative}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:attr.Cumulative}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{deprecated}\sphinxstyleindexpageref{using/libraries/writing:\detokenize{coq:attr.deprecated}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{export}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:attr.export}}
\indexspace
\bigletter{g}
\item\relax\sphinxstyleindexentry{global}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:attr.global}}
\indexspace
\bigletter{l}
\item\relax\sphinxstyleindexentry{local}\sphinxstyleindexpageref{language/core/modules:\detokenize{coq:attr.local}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{Monomorphic}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:attr.Monomorphic}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{NonCumulative}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:attr.NonCumulative}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{Polymorphic}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:attr.Polymorphic}}
\item\relax\sphinxstyleindexentry{Private}\sphinxstyleindexpageref{language/core/variants:\detokenize{coq:attr.Private}}
\item\relax\sphinxstyleindexentry{private(matching)}\sphinxstyleindexpageref{language/core/variants:\detokenize{coq:attr.private(matching)}}
\item\relax\sphinxstyleindexentry{program}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:attr.program}}
\item\relax\sphinxstyleindexentry{Program}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:attr.Program}}
\indexspace
\bigletter{r}
\item\relax\sphinxstyleindexentry{refine}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:attr.refine}}
\indexspace
\bigletter{u}
\item\relax\sphinxstyleindexentry{universes(cumulative)}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:attr.universes(cumulative)}}
\item\relax\sphinxstyleindexentry{universes(monomorphic)}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:attr.universes(monomorphic)}}
\item\relax\sphinxstyleindexentry{universes(noncumulative)}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:attr.universes(noncumulative)}}
\item\relax\sphinxstyleindexentry{universes(notemplate)}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:attr.universes(notemplate)}}
\item\relax\sphinxstyleindexentry{universes(polymorphic)}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:attr.universes(polymorphic)}}
\item\relax\sphinxstyleindexentry{universes(template)}\sphinxstyleindexpageref{language/core/inductive:\detokenize{coq:attr.universes(template)}}
\item\relax\sphinxstyleindexentry{using}\sphinxstyleindexpageref{proofs/writing-proofs/proof-mode:\detokenize{coq:attr.using}}
\end{sphinxtheindex}

\renewcommand{\indexname}{Index}
\printindex
\end{document}