diff options
author | filliatr <filliatr@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2000-12-12 22:36:15 +0000 |
---|---|---|
committer | filliatr <filliatr@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2000-12-12 22:36:15 +0000 |
commit | b6018c78b25da14d4f44cf10de692f968cba1e98 (patch) | |
tree | c152b9761b70cbc554efdc2f05f3a995444ed259 /doc | |
parent | 88e2679b89a32189673b808acfe3d6181a38c000 (diff) |
Initial revision
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@8143 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'doc')
46 files changed, 23826 insertions, 0 deletions
diff --git a/doc/.cvsignore b/doc/.cvsignore new file mode 100644 index 000000000..261566e34 --- /dev/null +++ b/doc/.cvsignore @@ -0,0 +1,26 @@ +*.blg +*.ind +*.ilg +*.v.tex +*.pdf +euclid.ml +heapsort.ml +avl.ml +*.bbl +www +coq-docs-html +Reference-Manual.atoc +Reference-Manual.tacidx Reference-Manual.tacind Reference-Manual.comind +Reference-Manual.comidx Reference-Manual.errind Reference-Manual.erridx +Reference-Manual.sh +Anomalies.dvi.gz Anomalies.ps.gz Changes.dvi.gz Changes.ps.gz Library.dvi.gz Library.ps.gz Reference-Manual-addendum.ps.gz Reference-Manual-all.dvi.gz Reference-Manual-all.ps.gz Reference-Manual-base.ps.gz Tutorial.dvi.gz Tutorial.ps.gz +Reference-Manual-base.dvi.gz +Reference-Manual-addendum.dvi.gz +Tutorial.pdf.gz +Reference-Manual.pdf.gz +Library.pdf.gz +Changes.pdf.gz +auto +all-ps-docs.tar +doc-html.tar.gz +all-ps-docs.tar.gz diff --git a/doc/AddRefMan-pre.tex b/doc/AddRefMan-pre.tex new file mode 100644 index 000000000..2f0b52834 --- /dev/null +++ b/doc/AddRefMan-pre.tex @@ -0,0 +1,46 @@ +\addtocontents{sh}{BEGINADDENDUM=\thepage} +\coverpage{Addenddum to the Reference Manual}{\ } +\addcontentsline{toc}{part}{Additionnal documentation} +\setheaders{Presentation of the Addendum} +\section*{Presentation of the Addendum} + +Here you will find several pieces of additional documentation for the +\Coq\ Reference Manual. Each of this chapters is concentrated on a +particular topic, that should interest only a fraction of the \Coq\ +users : that's the reason why they are apart from the Reference +Manual. + +\begin{description} + +\item[Cases] This chapter details the use of generalized pattern-matching. + It is contributed by Cristina Cornes. + +\item[Coercion] This chapter details the use of the coercion mechanism. + It is contributed by Amokrane Saïbi. + +\item[Extraction] This chapter explains how to extract in practice ML + files from $\FW$ terms. + +\item[Natural] This chapter is due to Yann Coscoy. It is the user + manual of the tools he wrote for printing proofs in natural + language. At this time, French and English languages are supported. + +\item[Omega] \texttt{Omega}, written by Pierre Crégut, solves a whole + class of arithmetic problems. + +\item[Program] The \texttt{Program} technology intends to inverse the + extraction mechanism. It allows the developments of certified + programs in \Coq. This chapter is due to Catherine Parent. + +\item[Ring] \texttt{Ring} is a tactic to do AC rewriting. This + chapter explains how to use it and how it works. + +\end{description} + +\atableofcontents + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/Anomalies.tex b/doc/Anomalies.tex new file mode 100755 index 000000000..8e23fa602 --- /dev/null +++ b/doc/Anomalies.tex @@ -0,0 +1,34 @@ +\documentclass[11pt]{article} + +\input{./title} + +\title{Known bugs of {\sf Coq} V6.2} +\author{\ } +\begin{document} +\maketitle + +\begin{itemize} + +\item {\tt Program} may fail to build pattern in {\tt Cases} +expressions. Instead an old style {\tt Case} expression without +patterns is generated. + +\item The option {\tt Set Printing Synth} sometimes fails to decide if +a elimination predicates is synthetisable. If a term printed without +the elimination predicate is not correctly re-interpreted by Coq, then +turn off the {\tt Printing Synth} mode. + +\item {\tt Unfold} and {\tt Pattern} may incorrectly number the +occurrences of constants or subterms when {\tt Cases} expression are involved. + +\item \texttt{Transparent} and \texttt{Opaque} are not synchronous + with the \texttt{Reset} mecanism. If a constant was transparent at + point \texttt{A}, if you set it opaque and do \texttt{Reset A}, it + is still opaque and that may cause problems if you try to replay + tactic scripts between \texttt{A} and the current point. + +\end{itemize} + +\end{document} + +% $Id$ diff --git a/doc/Cases.tex b/doc/Cases.tex new file mode 100644 index 000000000..559c9e15b --- /dev/null +++ b/doc/Cases.tex @@ -0,0 +1,610 @@ +\achapter{ML-style pattern-matching}\defaultheaders +\aauthor{Cristina Cornes} + +\label{Mult-Cases-full} +\ttindex{Cases} +\index{ML-like patterns} + +This section describes the full form of pattern-matching in {\Coq} terms. + +The current implementation contains two strategies, one for compiling +non-dependent case and another one for dependent case. + +\asection{Patterns}\label{implementation} +The full syntax of {\tt Cases} is presented in figure \ref{cases-grammar}. +Identifiers in patterns are either constructor names or variables. Any +identifier that is not the constructor of an inductive or coinductive +type is considered to be a variable. A variable name cannot occur more +than once in a given pattern. + +If a pattern has the form $(c~\vec{x})$ where $c$ is a constructor +symbol and $\vec{x}$ is a linear vector of variables, it is called +{\em simple}: it is the kind of pattern recognized by the basic +version of {\tt Cases}. If a pattern is +not simple we call it {\em nested}. + +A variable pattern matches any value, and the identifier is bound to +that value. The pattern ``\texttt{\_}'' (called ``don't care'' or +``wildcard'' symbol) also matches any value, but does not binds anything. It +may occur an arbitrary number of times in a pattern. Alias patterns +written \texttt{(}{\sl pattern} \texttt{as} {\sl identifier}\texttt{)} are +also accepted. This pattern matches the same values as {\sl pattern} +does and {\sl identifier} is bound to the matched value. A list of +patterns is also considered as a pattern and is called {\em multiple +pattern}. + +Note also the annotation is mandatory when the sequence of equation is +empty. + +\begin{figure}[t] +\fbox{\parbox{\linewidth}{ +\begin{tabular}{rcl} +{\nestedpattern} & := & {\ident} \\ + & $|$ & \_ \\ + & $|$ & \texttt{(} {\ident} \nelist{\nestedpattern}{} \texttt{)} \\ + & $|$ & \texttt{(} {\nestedpattern} \texttt{as} {\ident} \texttt{)} \\ + & $|$ & \texttt{(} {\nestedpattern} \texttt{,} {\nestedpattern} \texttt{)} \\ + & $|$ & \texttt{(} {\nestedpattern} \texttt{)} \\ + &&\\ + +{\multpattern} & := & \nelist{nested\_pattern}{} \\ + && \\ + +{\exteqn} & := & {\multpattern} \texttt{=>} {\term} \\ + && \\ + +{\term} & := & + \zeroone{\annotation} \texttt{Cases} \nelist{\term}{} \texttt{of} + \sequence{\exteqn}{$|$} \texttt{end} \\ +\end{tabular} +}} +\caption{Extended Cases syntax} +\label{cases-grammar} +\end{figure} + +Since extended {\tt Cases} expressions are compiled into the primitive +ones, the expressiveness of the theory remains the same. Once the +stage of parsing has finished only simple patterns remain. An easy way +to see the result of the expansion is by printing the term with +\texttt{Print} if the term is a constant, or using the command +\texttt{Check}. + +The extended \texttt{Cases} still accepts an optional {\em elimination +predicate} enclosed between brackets \texttt{<>}. Given a pattern +matching expression, if all the right hand sides of \texttt{=>} ({\em +rhs} in short) have the same type, then this term can be sometimes +synthesized, and so we can omit the \texttt{<>}. Otherwise we have +toprovide the predicate between \texttt{<>} as for the basic +\texttt{Cases}. + +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{coq_example} +Fixpoint max [n,m:nat] : nat := + Cases n of + O => m + | (S n') => Cases m of + O => (S n') + | (S m') => (S (max n' m')) + end + end. +\end{coq_example} + +Using multiple patterns in the definition allows to write: + +\begin{coq_example} +Reset max. +Fixpoint max [n,m:nat] : nat := + Cases n m of + O _ => m + | (S n') O => (S n') + | (S n') (S m') => (S (max n' m')) + end. +\end{coq_example} + +which will be compiled into the previous form. + +The strategy examines patterns from left to right. A \texttt{Cases} expression +is generated {\bf only} when there is at least one constructor in the +column of patterns. For example: + +\begin{coq_example} +Check [x:nat]<nat>Cases x of y => y end. +\end{coq_example} + +We can also use ``\texttt{as} patterns'' to associate a name to a +sub-pattern: + +\begin{coq_example} +Reset max. +Fixpoint max [n:nat] : nat -> nat := + [m:nat] Cases n m of + O _ => m + | ((S n') as N) O => N + | (S n') (S m') => (S (max n' m')) + end. +\end{coq_example} + +Here is now an example of nested patterns: + +\begin{coq_example} +Fixpoint even [n:nat] : bool := + Cases n of + O => true + | (S O) => false + | (S (S n')) => (even n') + end. +\end{coq_example} + +This is compiled into: + +\begin{coq_example} +Print even. +\end{coq_example} + +In the previous examples patterns do not conflict with, but +sometimes it is comfortable to write patterns that admits a non +trivial superposition. Consider +the boolean function \texttt{lef} that given two natural numbers +yields \texttt{true} if the first one is less or equal than the second +one and \texttt{false} otherwise. We can write it as follows: + +\begin{coq_example} +Fixpoint lef [n,m:nat] : bool := + Cases n m of + O x => true + | x O => false + | (S n) (S m) => (lef n m) + end. +\end{coq_example} + +Note that the first and the second multiple pattern superpose because +the couple of values \texttt{O O} matches both. Thus, what is the result +of the function on those values? To eliminate ambiguity we use the +{\em textual priority rule}: we consider patterns ordered from top to +bottom, then a value is matched by the pattern at the $ith$ row if and +only if is not matched by some pattern of a previous row. Thus in the +example, +\texttt{O O} is matched by the first pattern, and so \texttt{(lef O O)} +yields \texttt{true}. + +Another way to write this function is: + +\begin{coq_example} +Reset lef. +Fixpoint lef [n,m:nat] : bool := + Cases n m of + O x => true + | (S n) (S m) => (lef n m) + | _ _ => false + end. +\end{coq_example} + + +Here the last pattern superposes with the first two. Because +of the priority rule, the last pattern +will be used only for values that do not match neither the first nor +the second one. + +Terms with useless patterns are accepted by the +system. For example, +\begin{coq_example} +Check [x:nat]Cases x of O => true | (S _) => false | x => true end. +\end{coq_example} + +is accepted even though the last pattern is never used. +Beware, the +current implementation rises no warning message when there are unused +patterns in a term. + + + +\asection{About patterns of parametric types} +When matching objects of a parametric type, constructors in patterns +{\em do not expect} the parameter arguments. Their value is deduced +during expansion. + +Consider for example the polymorphic lists: + +\begin{coq_example} +Inductive List [A:Set] :Set := + nil:(List A) +| cons:A->(List A)->(List A). +\end{coq_example} + +We can check the function {\em tail}: + +\begin{coq_example} +Check [l:(List nat)]Cases l of + nil => (nil nat) + | (cons _ l') => l' + end. +\end{coq_example} + + +When we use parameters in patterns there is an error message: +\begin{coq_example} +Check [l:(List nat)]Cases l of + (nil nat) => (nil nat) + | (cons nat _ l') => l' + end. +\end{coq_example} + + + +\asection{Matching objects of dependent types} +The previous examples illustrate pattern matching on objects of +non-dependent types, but we can also +use the expansion strategy to destructure objects of dependent type. +Consider the type \texttt{listn} of lists of a certain length: + +\begin{coq_example} +Inductive listn : nat-> Set := + niln : (listn O) +| consn : (n:nat)nat->(listn n) -> (listn (S n)). +\end{coq_example} + +\asubsection{Understanding dependencies in patterns} +We can define the function \texttt{length} over \texttt{listn} by: + +\begin{coq_example} +Definition length := [n:nat][l:(listn n)] n. +\end{coq_example} + +Just for illustrating pattern matching, +we can define it by case analysis: +\begin{coq_example} +Reset length. +Definition length := [n:nat][l:(listn n)] + Cases l of + niln => O + | (consn n _ _) => (S n) + end. +\end{coq_example} + +We can understand the meaning of this definition using the +same notions of usual pattern matching. + +Now suppose we split the second pattern of \texttt{length} into two +cases so to give an +alternative definition using nested patterns: +\begin{coq_example} +Definition length1:= [n:nat] [l:(listn n)] + Cases l of + niln => O + | (consn n _ niln) => (S n) + | (consn n _ (consn _ _ _)) => (S n) + end. +\end{coq_example} + +It is obvious that \texttt{length1} is another version of +\texttt{length}. We can also give the following definition: +\begin{coq_example} +Definition length2:= [n:nat] [l:(listn n)] + Cases l of + niln => O + | (consn n _ niln) => (S O) + | (consn n _ (consn m _ _)) => (S (S m)) + end. +\end{coq_example} + +If we forget that \texttt{listn} is a dependent type and we read these +definitions using the usual semantics of pattern matching, we can conclude +that \texttt{length1} +and \texttt{length2} are different functions. +In fact, they are equivalent +because the pattern \texttt{niln} implies that \texttt{n} can only match +the value $0$ and analogously the pattern \texttt{consn} determines that \texttt{n} can +only match values of the form $(S~v)$ where $v$ is the value matched by +\texttt{m}. + +The converse is also true. If +we destructure the length value with the pattern \texttt{O} then the list +value should be $niln$. +Thus, the following term \texttt{length3} corresponds to the function +\texttt{length} but this time defined by case analysis on the dependencies instead of on the list: + +\begin{coq_example} +Definition length3 := [n:nat] [l: (listn n)] + Cases l of + niln => O + | (consn O _ _) => (S O) + | (consn (S n) _ _) => (S (S n)) + end. +\end{coq_example} + +When we have nested patterns of dependent types, the semantics of +pattern matching becomes a little more difficult because +the set of values that are matched by a sub-pattern may be conditioned by the +values matched by another sub-pattern. Dependent nested patterns are +somehow constrained patterns. +In the examples, the expansion of +\texttt{length1} and \texttt{length2} yields exactly the same term + but the +expansion of \texttt{length3} is completely different. \texttt{length1} and +\texttt{length2} are expanded into two nested case analysis on +\texttt{listn} while \texttt{length3} is expanded into a case analysis on +\texttt{listn} containing a case analysis on natural numbers inside. + + +In practice the user can think about the patterns as independent and +it is the expansion algorithm that cares to relate them. \\ + + +\asubsection{When the elimination predicate must be provided} +The examples given so far do not need an explicit elimination predicate +between \texttt{<>} because all the rhs have the same type and the +strategy succeeds to synthesize it. +Unfortunately when dealing with dependent patterns it often happens +that we need to write cases where the type of the rhs are +different instances of the elimination predicate. +The function \texttt{concat} for \texttt{listn} +is an example where the branches have different type +and we need to provide the elimination predicate: + +\begin{coq_example} +Fixpoint concat [n:nat; l:(listn n)] + : (m:nat) (listn m) -> (listn (plus n m)) + := [m:nat][l':(listn m)] + <[n:nat](listn (plus n m))>Cases l of + niln => l' + | (consn n' a y) => (consn (plus n' m) a (concat n' y m l')) + end. +\end{coq_example} + +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 type we need to provide +the elimination predicate for this multiple pattern. + +For example, an equivalent definition for \texttt{concat} (even though with a useless extra pattern) would have +been: + +\begin{coq_example} +Reset concat. +Fixpoint concat [n:nat; l:(listn n)] : (m:nat) (listn m) -> (listn (plus n m)) +:= [m:nat][l':(listn m)] + <[n,_:nat](listn (plus n m))>Cases l l' of + niln x => x + | (consn n' a y) x => (consn (plus n' m) a (concat n' y m x)) + end. +\end{coq_example} + +Note that this time, the predicate \texttt{[n,\_:nat](listn (plus n + m))} is binary because we +destructure both \texttt{l} and \texttt{l'} whose types have arity one. +In general, if we destructure the terms $e_1\ldots e_n$ +the predicate will be of arity $m$ where $m$ is the sum of the +number of dependencies of the type of $e_1, e_2,\ldots e_n$ +(the $\lambda$-abstractions +should correspond from left to right to each dependent argument of the +type of $e_1\ldots e_n$). +When the arity of the predicate (i.e. number of abstractions) is not +correct Coq rises an error message. For example: + +\begin{coq_example} +Fixpoint concat [n:nat; l:(listn n)] + : (m:nat) (listn m) -> (listn (plus n m)) := + [m:nat][l':(listn m)] + <[n:nat](listn (plus n m))>Cases l l' of + | niln x => x + | (consn n' a y) x => (consn (plus n' m) a (concat n' y m x)) + end. +\end{coq_example} + +\asection{Using pattern matching to write proofs} +In all the previous examples the elimination predicate does not depend +on the object(s) matched. The typical case where this is not possible +is when we write a proof by induction or a function that yields an +object of dependent type. An example of proof using \texttt{Cases} in +given in section \ref{Refine-example} + +For example, we can write +the function \texttt{buildlist} that given a natural number +$n$ builds a list length $n$ containing zeros as follows: + +\begin{coq_example} +Fixpoint buildlist [n:nat] : (listn n) := + <[n:nat](listn n)>Cases n of + O => niln + | (S n) => (consn n O (buildlist n)) + end. +\end{coq_example} + +We can also use multiple patterns whenever the elimination predicate has +the correct arity. + +Consider the following definition of the predicate less-equal +\texttt{Le}: + +\begin{coq_example} +Inductive LE : nat->nat->Prop := + LEO: (n:nat)(LE O n) +| LES: (n,m:nat)(LE n m) -> (LE (S n) (S m)). +\end{coq_example} + +We can use multiple patterns to write the proof of the lemma + \texttt{(n,m:nat) (LE n m)\/(LE m n)}: + +\begin{coq_example} +Fixpoint dec [n:nat] : (m:nat)(LE n m) \/ (LE m n) := + [m:nat] <[n,m:nat](LE n m) \/ (LE m n)>Cases n m of + O x => (or_introl ? (LE x O) (LEO x)) + | x O => (or_intror (LE x O) ? (LEO x)) + | ((S n) as N) ((S m) as M) => + Cases (dec n m) of + (or_introl h) => (or_introl ? (LE M N) (LES n m h)) + | (or_intror h) => (or_intror (LE N M) ? (LES m n h)) + end + end. +\end{coq_example} +In the example of \texttt{dec} the elimination predicate is binary +because we destructure two arguments of \texttt{nat} that is a +non-dependent type. Note the first \texttt{Cases} is dependent while the +second is not. + +In general, consider the terms $e_1\ldots e_n$, +where the type of $e_i$ is an instance of a family type +$[\vec{d_i}:\vec{D_i}]T_i$ ($1\leq i +\leq n$). Then to write \texttt{<}${\cal P}$\texttt{>Cases} $e_1\ldots +e_n$ \texttt{of} \ldots \texttt{end}, the +elimination predicate ${\cal P}$ should be of the form: +$[\vec{d_1}:\vec{D_1}][x_1:T_1]\ldots [\vec{d_n}:\vec{D_n}][x_n:T_n]Q.$ + +The user can also use \texttt{Cases} in combination with the tactic +\texttt{Refine} (see section \ref{Refine}) to build incomplete proofs +beginning with a \texttt{Cases} construction. + +\asection{When does the expansion strategy fail ?}\label{limitations} +The strategy works very like in ML languages when treating +patterns of non-dependent type. +But there are new cases of failure that are due to the presence of +dependencies. + +The error messages of the current implementation may be sometimes +confusing. When the tactic fails because patterns are somehow +incorrect then error messages refer to the initial expression. But the +strategy may succeed to build an expression whose sub-expressions are +well typed when the whole expression is not. In this situation the +message makes reference to the expanded expression. We encourage +users, when they have patterns with the same outer constructor in +different equations, to name the variable patterns in the same +positions with the same name. +E.g. to write {\small\texttt{(cons n O x) => e1}} +and {\small\texttt{(cons n \_ x) => e2}} instead of +{\small\texttt{(cons n O x) => e1}} and +{\small\texttt{(cons n' \_ x') => e2}}. +This helps to maintain certain name correspondence between the +generated expression and the original. + +Here is a summary of the error messages corresponding to each situation: + +\begin{itemize} +\item patterns are incorrect (because constructors are not applied to + the correct number of the arguments, because they are not linear or + they are wrongly typed) +\begin{itemize} +\item \sverb{In pattern } {\sl term} \sverb{the constructor } {\sl + ident} \sverb{expects } {\sl num} \sverb{arguments} + +\item \sverb{The variable } {\sl ident} \sverb{is bound several times + in pattern } {\sl term} + +\item \sverb{Constructor pattern: } {\sl term} \sverb{cannot match + values of type } {\sl term} +\end{itemize} + +\item the pattern matching is not exhaustive +\begin{itemize} +\item \sverb{This pattern-matching is not exhaustive} +\end{itemize} +\item the elimination predicate provided to \texttt{Cases} has not the + expected arity + +\begin{itemize} +\item \sverb{The elimination predicate } {\sl term} \sverb{should be + of arity } {\sl num} \sverb{(for non dependent case) or } {\sl + num} \sverb{(for dependent case)} +\end{itemize} + +\item the whole expression is wrongly typed, or the synthesis of + implicit arguments fails (for example to find the elimination + predicate or to resolve implicit arguments in the rhs). + + + There are {\em nested patterns of dependent type}, the elimination + predicate corresponds to non-dependent case and has the form + $[x_1:T_1]...[x_n:T_n]T$ and {\bf some} $x_i$ occurs {\bf free} in + $T$. Then, the strategy may fail to find out a correct elimination + predicate during some step of compilation. In this situation we + recommend the user to rewrite the nested dependent patterns into + several \texttt{Cases} with {\em simple patterns}. + + In all these cases we have the following error message: + + \begin{itemize} + \item {\tt Expansion strategy failed to build a well typed case + expression. There is a branch that mismatches the expected + type. The risen \\ type error on the result of expansion was:} + \end{itemize} + +\item because of nested patterns, it may happen that even though all + the rhs have the same type, the strategy needs dependent elimination + and so an elimination predicate must be provided. The system warns + about this situation, trying to compile anyway with the + non-dependent strategy. The risen message is: +\begin{itemize} +\item {\tt Warning: This pattern matching may need dependent + elimination to be compiled. I will try, but if fails try again + giving dependent elimination predicate.} +\end{itemize} + +\item there are {\em nested patterns of dependent type} and the + strategy builds a term that is well typed but recursive calls in fix + point are reported as illegal: +\begin{itemize} +\item {\tt Error: Recursive call applied to an illegal term ...} +\end{itemize} + +This is because the strategy generates a term that is correct w.r.t. +to the initial term but which does not pass the guard condition. In +this situation we recommend the user to transform the nested dependent +patterns into {\em several \texttt{Cases} of simple patterns}. Let us +explain this with an example. Consider the following definition of a +function that yields the last element of a list and \texttt{O} if it is +empty: + +\begin{coq_example} + Fixpoint last [n:nat; l:(listn n)] : nat := + Cases l of + (consn _ a niln) => a + | (consn m _ x) => (last m x) | niln => O + end. +\end{coq_example} + +It fails because of the priority between patterns, we know that this +definition is equivalent to the following more explicit one (which +fails too): + +\begin{coq_example*} + Fixpoint last [n:nat; l:(listn n)] : nat := + Cases l of + (consn _ a niln) => a + | (consn n _ (consn m b x)) => (last n (consn m b x)) + | niln => O + end. +\end{coq_example*} + +Note that the recursive call {\tt (last n (consn m b x))} is not +guarded. When treating with patterns of dependent types the strategy +interprets the first definition of \texttt{last} as the second +one\footnote{In languages of the ML family the first definition would + be translated into a term where the variable \texttt{x} is shared in + the expression. When patterns are of non-dependent types, Coq + compiles as in ML languages using sharing. When patterns are of + dependent types the compilation reconstructs the term as in the + second definition of \texttt{last} so to ensure the result of + expansion is well typed.}. Thus it generates a term where the +recursive call is rejected by the guard condition. + +You can get rid of this problem by writing the definition with +\emph{simple patterns}: + +\begin{coq_example} + Fixpoint last [n:nat; l:(listn n)] : nat := + <[_:nat]nat>Cases l of + (consn m a x) => Cases x of niln => a | _ => (last m x) end + | niln => O + end. +\end{coq_example} + +\end{itemize} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/Changes.tex b/doc/Changes.tex new file mode 100755 index 000000000..4eac45633 --- /dev/null +++ b/doc/Changes.tex @@ -0,0 +1,160 @@ +\documentclass[11pt]{article} +\usepackage[latin1]{inputenc} +\usepackage[T1]{fontenc} + +\input{./title} +\input{./macros} + +\begin{document} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Changes 6.3 ===> 6.3.1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\shorttitle{Changes from {\Coq} V6.3 to {\Coq} V6.3.1} + +This document describes the main differences between Coq V6.3 and +V6.3.1. This new version of Coq is characterized by fixed bugs, and +improvement of implicit arguments synthesis and speed in tactic +applications. + +\section{Changes overview} + +\subsection{Tactics} + + \begin{itemize} + + \item \texttt {Tauto} has been unable for a time to deal with +hypotheses with 2 imbricated implications. Now it should work. +\texttt {Intuition} now removes true, and therefore useless, +hypotheses.\\ + + \item Several bugs of the {\texttt Program} are fixed (but some + automatically generated names have changed and may lead to + incompatibilities). + + \item Bug with negative index in bindings fixed. + + \item Speed improvement: redondant checks when applying a tactic + have been turned off. For some tactics that don't make themselves + the expected verifications, it may result in incorrect proofs + detected only at Qed/Save time. In this last case, you can turn on + the -tac-debug flag to coqtop. + + \item The ``?'' in goals are now instantiated as soon as an instance + is known for them. + + \end{itemize} + +\subsection{Toplevel commands} + +\begin{description} + +\item Bug in \texttt{Time} fixed. + +\end{description} + +\subsection{Language} + + \begin{description} \item[Type reconstruction] The algorithm to + solve incomplete information in terms has been improved + furthermore. In particular question marks can be put in in place of + the type of abstracted variables and in Cases expressions. + + \item[Guarded cofixpoints] A weakness in the guardness condition + when a cofixpoint refers to another one has been corrected. + WARNING: the new criterion may refuse some olderly accepted + Cofixpoint definitions which actually are valid but for a reason + difficult to detect automatically. + + \item[Extraction] A bug was limiting the number of propositional + singleton inductive types (such has ``eq'') for which elimination + towards Set is valid. + + \end{description} + +\subsection{Incompatibilities} + + You could have to modify your vernacular source for the following + reasons: + + \begin{itemize} + + \item Some names of variables generated by the \texttt{Program} have + changed. + + \item {\texttt Intuition} now remove trye hypotheses. + + \item In all cases, the ``.vo'' files are not compatible and should + be recompiled. + + \end{itemize} + +\section{New users contributions} + + \begin{description} + + \item[Binary Decision Diagrams] provided by Kumar Verma (Dyade) + + \item[A distributed reference counter] (part of a + garbage collector) provided by Jean Duprat (ENS-Lyon) + +\end{description} + +\section{Installation procedure} + +\subsection{Uninstalling Coq} + +\paragraph{Warning} +It is strongly recommended to clean-up the V6.3 Coq library directory +before you install the new version. +Use the option to coqtop \texttt{-uninstall} that will remove +the binaries and the library files of Coq V6.3 on a Unix system. + +\subsection{OS Issues -- Requirements} + +\subsubsection{Unix users} +You need Objective Caml version 2.01 or later, and the corresponding +Camlp4 version to compile the system. Both are available by anonymous ftp +at: \\ +\verb|ftp://ftp.inria.fr/Projects/Cristal|. +\bigskip + +\noindent +Binary distributions are available for the following architectures: + +\bigskip +\begin{tabular}{l|c|r} +{\bf OS } & {\bf Processor} & {name of the package}\\ +\hline +Linux & 80386 and higher & coq-6.3.1-Linux-i386.tar.gz \\ +Solaris & Sparc & coq-6.3.1-solaris-sparc.tar.gz\\ +Digital & Alpha & coq-6.3.1-OSF1-alpha.tar.gz\\ +\end{tabular} +\bigskip + +There is also rpm packages for Linux. + +\bigskip + +If your configuration is in the above list, you don't need to install +Caml and Camlp4 and to compile the system: +just download the package and install the binaries in the right place. + +\subsubsection{MS Windows users} + +A binary distribution is available for PC under MS Windows 95/98/NT. +The package is named coq-6.3.1-win.zip. + +For installation information see the +files INSTALL.win and README.win. + +\end{document} + +% Local Variables: +% mode: LaTeX +% TeX-master: t +% End: + + +% $Id$ + diff --git a/doc/ChangesV6-2.tex b/doc/ChangesV6-2.tex new file mode 100755 index 000000000..1485f4914 --- /dev/null +++ b/doc/ChangesV6-2.tex @@ -0,0 +1,921 @@ +\documentclass[11pt]{article} +\usepackage[latin1]{inputenc} +\usepackage[T1]{fontenc} + +\input{./title} +\input{./macros} + +\begin{document} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Changes 6.1 ===> 6.2 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\coverpage{Changes from {\Coq} V6.1 to {\Coq} V6.2}{\ } + +This document describes the main differences between Coq V6.1 and +V6.2. This new version of Coq is characterized by an acceleration of +parsing, loading and reduction, by a more user-friendly syntax, and by +new tactics and management tools. +We refer to the reference manual +for a more precise description of the new features. + +See the ASCII file \texttt{CHANGES} available by FTP with \Coq\ for +the minor changes of the bug-fix releases 6.2.1 and 6.2.2. + + +\section{Changes overview} + +\begin{itemize} + +\item \textbf{Syntax} + +\begin{description} + + \item[New syntax for defining parsing and pretty-printing rules.]{\ + + The \texttt{Grammar} and + \texttt{Syntax} declarations are more readable and more symmetric.} + + \item[\texttt{Cases} vs \texttt{Case}]{\ + + The constructions defined by cases are + now printed with the ML-style \texttt{Cases} syntax. The + \texttt{Case} syntax should no longer be used.} + + \item[New syntax for the existential and universal quantifiers.]{\ + + \texttt{(EX x:A | P)}, \texttt{(EX x| P)}, \texttt{(EX x:A | P \& + Q)}, \texttt{(EX x | P \& Q)}, + \texttt{(ALL x:A | P)} and + \texttt{(ALL x | P)} are alternative + syntax for \texttt{(Ex [x:A]P)}, \texttt{(Ex2 [x:A]P [x:A]Q)} + and \texttt{(All [x:A]P)}, the syntax \texttt{<A>Ex(P), + <A>Ex(P,Q)} and \texttt{<A>All(P)} are no longer supported.} + + \item[Natural syntax for the ... naturals.]{\ + + With the {\tt Arith} theory, you can + now type \texttt{(3)} for \texttt{(S (S (S O)))}}. + + \item[Natural syntax for expressions of integer arithmetic.]{\ + + With the {\tt ZArith} theory, you can + type e.g. \texttt{`3 <= x - 4 < 7`}.} + +\end{description} + +\item \textbf{Tactics} + + \begin{itemize} + + \item New mechanism to define parameterized tactics (see + section~\ref{parameterised}). + + \item New tactic \texttt{Decompose} to decompose a + complex proposition in atomic ones (see + section~\ref{decompose}). + + \item New tactics \texttt{Decide Equality} and + \texttt{Compare} for deciding the equality of two + inductive objects. + + \item \texttt{Intros} has been extended such that it takes arguments + denoting patterns and accordingly to this patterns, performs decomposition of arguments ranging + over inductive definitions as well as introduction (see section~\ref{intros}). + + \item \texttt{Tauto} is extended to + work also on connectives defined by the user and on informative + types (see section~\ref{tauto}). + + \item The {\bf equality} tactics, especially \texttt{Rewrite}, + \texttt{Transitivity}, \texttt{Symmetry} and \texttt{Reflexivity}, + works now independently of the universe that the equality + inhabits (see section~\ref{equality}). + + \item New experimental tactic \texttt{Refine}: a kind of + \texttt{Exact} with typed holes that are transformed into + subgoals (see + section~\ref{refine}). + + \item The tactical \texttt{Abstract} allow to automatically + divide a big proof into smaller lemmas. It may improve the + efficiency of the \texttt{Save} procedure (see section~\ref{abstract}). + + \item The tactics \texttt{Rewrite} and \texttt{Rewrite in} now + accept bindings as tactics \texttt{Apply} and \texttt{Elim}. + + \item The tactic \texttt{Rewrite} now fails when no rewriting can be + done. So you must use \texttt{Try Rewrite} to get the old behavior. + + \end{itemize} + +\item \textbf{New toplevel commands.} + + \begin{description} + + \item[Precise location of errors.]{\ + + At toplevel, when possible, \Coq\ + underlines the portion of erroneous vernac source. When compiling, + it tells the line and characters where the error took place. The + output is compatible with the \texttt{next-error} mechanism of GNU + Emacs.} + + \item[New reduction functions.]{\ + A more precise control on what is reduced is now + possible in tactics. All toplevel reductions are performed through the + \texttt{Eval} command. The commands \texttt{Compute} and + \texttt{Simplify} do not exist any longer, they are replaced by + the commands \texttt{Eval Compute in} and \texttt{Eval Simpl in}. + In addition, + \texttt{Eval} now takes into consideration the hypotheses of the + current goal in order to type-check the term to be reduced + (see section~\ref{reductions}).} + + \end{description} + +\item \textbf{Libraries} + + \begin{description} + + \item[Arithmetic on Z.]{\ + + Pierre Cr\'egut's arithmetical library on integers (the set Z) is now + integrated to the standard library. + \texttt{ZArith} contains basic + definitions, theorems, and syntax rules that allow users of \texttt{ZArith} + to write formulas such as $3+(x*y) < z \le 3+(x*y+1)$ in the + natural way~(see section~\ref{zarith}). + } + + \item[\texttt{SearchIsos} : a tool to search through the standard library]{ + + The \texttt{SearchIsos} tool se\-arches terms by their + types and modulo type isomorphisms. There are two ways to use + \texttt{SearchIsos}: + + \begin{itemize} + \item Search a theorem in the current environment with the new + \texttt{SearchIsos} command in an interactive session + \item Search a theorem in the whole Library using the external tool + \texttt{coqtop -searchisos} + \end{itemize} } + + \item The \texttt{Locate} vernac command can now locate the + module in which a term is defined in a \texttt{coqtop} session. You can + also ask for the exact location of a file or a module that lies + somewhere in the load path. + +\end{description} + +\item \textbf{Extraction} + + \begin{description} + + \item Extraction to Haskell available + + \end{description} + +\item \textbf{Improved Coq efficiency} + + \begin{description} + + \item[Parsing] + + Thanks to a new grammar implementation based on Daniel de + Rauglaudre's Camlp4 system, parsing is now several times faster. The + report of syntax errors is more precise. + + \item[Cleaning up the tactics source]{\ + + Source code of the tactics has been revisited, so that the user can + implement his/her own tactics more easily. The internal ML names + for tactics have been normalized, and they are organized in + different files. See chapter ``Writing your own tactics'' in the + Coq reference manual.} + + \end{description} + +\item \textbf{Incompatibilities} + + You could have to modify your vernacular source for the following + reasons: + + \begin{itemize} + + \item You use the name \texttt{Sum} which is now a keyword. + \item You use the syntax \texttt{<A>Ex(P)}, \texttt{<A>Ex2(P,Q)} or + \texttt{<A>All(P)}. + + \item You use Coq \texttt{Grammar} or \texttt{Syntax} commands. + In this case, see section + \ref{parsing-printing} to know how to modify your parsing or printing + rules. + + \item You use Coq \texttt{Call} to apply a tactic abbreviation + declared using \texttt{Tactic Definition}. These tactics can be + directly called, just remove the \texttt{Call} prefix. + + \item \texttt{Require} semantics. The Coq V6.1 \texttt{Require} + command did not behave as described in the reference manual. + It has been corrected.\\ + The Coq V6.2 behavior is now the following. + Assume a file \texttt{A} containing a + command \texttt{Require B} is compiled. Then the command + \texttt{Require A} loads the module \texttt{B} but the definitions + in \texttt{B} are not visible. In order to see theses definitions, + a further \texttt{Require B} is + needed or you should write \texttt{Require Export B} instead of + \texttt{Require B} inside the file \texttt{A}. \\ + The Coq V6.1 behavior of \texttt{Require} was equivalent to the + Coq V6.2 \texttt{Require Export} command. + \item \texttt{Print Hint} now works only in proof mode and displays + the hints that apply to the current goal. \texttt{Print Hint *} + works as the old \texttt{Print Hint} command and displays the complete + hints table. + + \end{itemize} + + In addition, it is strongly recommended to use now the {\tt Cases} + pattern-matching operator rather than the intended to disappear {\tt + Case} operator. + +\item \textbf{Documentation} + The Reference Manual has been rearranged and + updated. The chapters on syntactic extensions, and user-defined + tactics have been completely rewritten. + + \begin{itemize} + \item We made a big effort to make the Reference Manual better and + more precise. The paper documentation is now divided in three + parts: + \begin{enumerate} + \item The Reference Manual, that documents the language (part I), + a brief explanation of each command and tactic (part II), the + users extensions for syntax and tactics (part III), the tools + (part IV); + + \item The Addendum to Reference Manual (part V), that contains + more detailed explanations about extraction, printing proofs in + natural language, tactics such as Omega, Ring and Program, + coercions and Cases compilation. + + \item The Tutorial, an introduction to Coq for the new user, that + has not much changed + \end{enumerate} + + \item The Hyper-Text documentation has been much improved. Please + check our web page \verb!http://pauillac.inria.fr/coq!. It is + possible to perform searches in the standard Library by name or by + type (with SearchIsos), and of course to read the HTML version + of the documentation. + \end{itemize} + +\end{itemize} + +\section{New tactics} + + +\subsection{Proof of imperative programs} + +A new tactic to establish correctness and termination of imperative +(and functional) programs is now available, in the \Coq\ module +\texttt{Programs}. This tactic, called \texttt{Correctness}, is +described in the chapter 18 of the \Coq\ Reference Manual. + + +\subsection{Defining parameterized tactics} +\label{parameterised} +It is possible to define tactics macros, taking terms as arguments +using the \texttt{Tactic Definition} command. + +These macros can be called directly (in Coq V6.1, a prefix +\texttt{Call} was used). +Example: + +\begin{coq_example*} +Tactic Definition DecideEq [$a $b] := + [<:tactic:< + Destruct $a; + Destruct $b; + Auto; + (Left;Discriminate) Orelse (Right;Discriminate)>>]. +Inductive Set Color := Blue:Color | White:Color | Red:Color | Black:Color. +\end{coq_example*} + +\begin{coq_example} +Theorem eqColor: (c1,c2:Color){c1=c2}+{~c1=c2}. +DecideEq c1 c2. +\end{coq_example} +\begin{coq_example*} +Qed. +\end{coq_example*} + +\subsection{Intros}\label{intros} +The tactic \texttt{Intros} can now take a pattern as argument. A +pattern is either +\begin{itemize} +\item a variable +\item a list of patterns : $p_1~\ldots~p_n$ +\item a disjunction of patterns : $[p_1~|~~\ldots~|~p_n]$ +\item a conjunction of patterns : $(p_1,\ldots,p_n)$ +\end{itemize} + +The behavior of \texttt{Intros} is defined inductively over the +structure of the pattern given as argument: +\begin{itemize} +\item introduction on a variable behaves like before; +\item introduction over a +list of patterns $p_1~\ldots~p_n$ is equivalent to the sequence of +introductions over the patterns namely : +\texttt{Intros $p_1$;\ldots; Intros $p_n$}, the goal should start with +at least $n$ products; +\item introduction over a +disjunction of patterns $[p_1~|~~\ldots~|~p_n]$, it +introduces a new variable $X$, its type should be an inductive definition with $n$ +constructors, then it performs a case analysis over $X$ +(which generates $n$ subgoals), it +clears $X$ and performs on each generated subgoals the corresponding +\texttt{Intros}~$p_i$ tactic; +\item introduction over a +conjunction of patterns $(p_1,\ldots,p_n)$, it +introduces a new variable $X$, its type should be an inductive definition with $1$ +constructor with (at least) $n$ arguments, then it performs a case analysis over $X$ +(which generates $1$ subgoal with at least $n$ products), it +clears $X$ and performs an introduction over the list of patterns $p_1~\ldots~p_n$. +\end{itemize} +\begin{coq_example} +Lemma intros_test : (A,B,C:Prop)(A\/(B/\C))->(A->C)->C. +Intros A B C [a|(b,c)] f. +Apply (f a). +Proof c. +\end{coq_example} +\subsection{Refine}\label{refine} +This tactics takes a term with holes as argument. + +It is still experimental and not automatically loaded. It can +be dynamically loaded if you use the byte-code version of Coq; +with the version in native code, you have to use the \texttt{-full} option. + +\Example +\begin{coq_example*} +Require Refine. +Inductive Option: Set := Fail : Option | Ok : bool->Option. +\end{coq_example} +\begin{coq_example} +Definition get: (x:Option)~x=Fail->bool. +Refine + [x:Option]<[x:Option]~x=Fail->bool>Cases x of + Fail => ? + | (Ok b) => [_:?]b end. +Intros;Absurd Fail=Fail;Trivial. +\end{coq_example} +\begin{coq_example*} +Defined. +\end{coq_example*} + +\subsection{Decompose}\label{decompose} +This tactic allows to recursively decompose a +complex proposition in order to obtain atomic ones. +Example: + +\begin{coq_eval} +Reset Initial. +\end{coq_eval} +\begin{coq_example} +Lemma ex1: (A,B,C:Prop)(A/\B/\C \/ B/\C \/ C/\A) -> C. +Intros A B C H; Decompose [and or] H; Assumption. +\end{coq_example} +\begin{coq_example*} +Qed. +\end{coq_example*} + + +\subsection{Tauto}\label{tauto} +This tactic has been extended to work also on +connectives defined by the user as well as on informative types. +Example: + +\begin{coq_example*} +Inductive AND4 [A:Set;B,C,D:Prop] : Set := + tuple4 : A->B->C->D->(AND4 A B C D). +\end{coq_example*} +\begin{coq_example} +Lemma ex2: (B,C,D:Prop)(AND4 nat B C D)->(AND4 nat C D B). +Tauto. +\end{coq_example} +\begin{coq_example*} +Qed. +\end{coq_example*} + +\subsection{Tactics about Equality}\label{equality} +\texttt{Rewrite}, \texttt{Transitivity}, \texttt{Symmetry}, +\texttt{Reflexivity} and other tactics associated to equality predicates work +now independently of the universe that the equality inhabits. +Example: + +\begin{coq_example*} +Inductive EQ [A:Type] : Type->Prop := reflEQ : (EQ A A). +\end{coq_example*} +\begin{coq_example} +Lemma sym_EQ: (A,B:Type)(EQ A B)->(EQ B A). +Intros;Symmetry;Assumption. +\end{coq_example} +\begin{coq_example*} +Qed. +\end{coq_example*} + +\begin{coq_example} +Lemma trans_idT: (A,B:Type)(A===Set)->(B===Set)->A===B. +Intros A B X Y;Rewrite X;Symmetry;Assumption. +\end{coq_example} +\begin{coq_example*} +Qed. +\end{coq_example*} + + +\subsection{The tactical \texttt{Abstract}}~\label{abstract} +From outside, typing \texttt{Abstract \tac} is the same that +typing \tac. If \tac{} completely solves the current goal, it saves an auxiliary lemma called +{\ident}\texttt{\_subproof}\textit{n} where {\ident} is the name of the +current goal and \textit{n} is chosen so that this is a fresh +name. This lemma is a proof of the current goal, generalized over the +local hypotheses. + +This tactical is useful with tactics such that \texttt{Omega} and +\texttt{Discriminate} that generate big proof terms. With that tool +the user can avoid the explosion at time of the \texttt{Save} command +without having to cut ``by hand'' the proof in smaller lemmas. + +\begin{Variants} +\item \texttt{Abstract {\tac} using {\ident}}. Gives explicitly the + name of the auxiliary lemma. +\end{Variants} +\begin{coq_example*} +Lemma abstract_test : (A,B:Prop)A/\B -> A\/B. +\end{coq_example*} +\begin{coq_example} +Intros. +Abstract Tauto using sub_proof. +Check sub_proof. +\end{coq_example} +\begin{coq_example*} +Qed. +\end{coq_example*} +\begin{coq_example} +Print abstract_test. +\end{coq_example} + + +\subsection{Conditional $tac$ Rewrite $c$} +This tactics acts as \texttt{Rewrite} and applies a given tactic on the +subgoals corresponding to conditions of the rewriting. +See the Reference Manual for more details. + + +\section{Changes in concrete syntax} + +\subsection{The natural grammar for arithmetic} +\label{zarith} +There is a new syntax of signed integer arithmetic. However the +syntax delimiters were \verb=[|= and \verb=|]= in the beta-version. In +the final release of 6.2, it's two back-quotes \texttt{`} and \texttt{`}. + +Here is an example: +\begin{coq_eval} +Reset Initial. +\end{coq_eval} + +\begin{coq_example*} +Require ZArith. +Variables x,y,z:Z. +Variables f,g:Z->Z. +\end{coq_example*} +\begin{coq_example} +Check ` 23 + (f x)*45 - 34 `. +Check Zplus_sym. +Check ` x < (g y) <= z+3 `. +Check ` 3+ [if true then ` 4 ` else (f x)] `. +SearchIsos (x,y,z:Z) ` x+(y+z) = (x+y)+z `. +\end{coq_example} + +\begin{coq_eval} +Reset x. +\end{coq_eval} + +Arithmetic expressions are enclosed between \verb=`= and \verb=`=. It can +be: +\begin{itemize} +\item integers +\item any of the operators \verb|+|, \verb|-| and \verb|*| +\item functional application +\item any of the relations \verb|<|, \verb|<=|, \verb|>=|, \verb|>|, +\verb|=| and \verb|<>| +\end{itemize} + +Inside an arithmetic expression, you can type an arbitrary Coq +expression provided it is escaped with \verb|[ ]|. There is also +shortcuts such as $x < y \le z$ which means $x<y \wedge y \le z$. + +\begin{coq_example} +Lemma ex3 : (x:Z)` x>0 ` -> ` x <= 2*x <= 4*x `. +Split. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} +\subsection{The new \texttt{Grammar} and \texttt{Syntax}} +\label{parsing-printing} + +The leading idea in the {\tt Grammar} and {\tt Syntax} command syntax +changes is to unify and simplify them. + +\subsubsection{Syntax changes for \texttt{Grammar} declarations (parsing rules)} + +Each \texttt{Grammar} rule now needs to be named, as \texttt{Syntax} +rules do. Although they are just comments, it is advised to use distinct +names for rules. + +The syntax of an ordinary grammar rule is now: + +\[ +\texttt{Grammar}~\textit{GrammarName}~\textit{EntryName}~\texttt{:=}~ + \textit{RuleName}~ \texttt{[} \textit{Pattern} \texttt{] -> [} \textit{Action} +\texttt{]}. +\] +\paragraph{Parametric rules} + +Parametric grammars does not exist any longer. Their main use was to +write left associative rules. For that, there is a simplest way based +on a new grammar builder \texttt{LEFTA} (and grammar builder +\texttt{RIGHTA} and \texttt{NONA} as well). + +For instance, the grammar in V6.1 style + +\begin{verbatim} +Grammar natural fact := + [ final($c) factprod[[$c]]($r) ] -> [$r]. + +Grammar natural factprod[$p] := + [ ] -> [$p] +| [ "*" final($c) factprod[[<<(mult $p $c)>>]]($r)] -> [$r]. +\end{verbatim} +should now be written +\begin{verbatim} +Grammar natural fact := + LEFTA + fact_final [ final($c) ] -> [$c] + | fact_prod [ final($p) "*" final($c) ] -> [ <<(mult $p $c)>> ]. +\end{verbatim} + +\subsubsection{Internal abstract syntax tree (ast) changes} + +The syntax of internal abstract syntax tree (ast) has also been +modified. Most users, which only uses \verb|<<| ... \verb|>>| in the +right-hand side of the grammar rules are not concerned with that. +For the others, it should be noted that now there are two kinds of +production for grammar rules: ast and lists of asts. + +A rule that produces a list of asts should be declared of this type by +inserting ``\texttt{:List}'' just after the grammar name. + +The ast constructors \verb!$CONS!, \verb!$NIL!, \verb!$APPEND!, +\verb!$PRIM!, \verb!SOME! and \verb!$OPER! do not +exist any longer. A simple juxtaposition is used to build ast lists. +For an empty +list, just put nothing. The old \verb!($OPER{Foo} ($CONS $c1 $c2))! +becomes \verb!(Foo $c1 $c2)!. The old \verb!$SLAML! is now \verb!$SLAM!. + +The constructor \verb!$LIST! has a new meaning. It serves to cast an +ast list variable into an ast. + +For instance, the following grammar rules in V6.1 style: +\begin{verbatim} +Grammar vernac eqns := + [ "|" ne_command_list($ts) "=>" command($u) eqns($es) ] + -> [($CONS ($OPER{COMMANDLIST} ($CONS $u $ts)) $es)]. +| [ ] -> [($LIST)] + +with vernac := + [ "Foo" "Definition" identarg($idf) command($c) ":=" eqns($eqs) "." ] + -> [($OPER{FooDefinition} ($CONS $idf ($CONS $c $eqs)))] +\end{verbatim} +can be written like this in V6.2 +\begin{verbatim} +Grammar vernac eqns : List := + eqns_cons [ "|" ne_command_list($ts) "=>" command($u) eqns($es) ] + -> [ (COMMANDLIST $u ($LIST $ts)) ($LIST $es)] +| eqns_nil [ ] -> [ ]. + +with vernac := + rec_def [ "Foo" "Definition" identarg($idf) command($c) ":=" eqns($eqs) "." ] + -> [(FooDefinition $idf $c ($LIST $eqs))]. +\end{verbatim} + + +\subsubsection{Syntax changes for \texttt{Syntax} declarations + (printing rules)} + +The new syntax for printing rules follows the one for parsing rules. In +addition, there are indications of associativity, precedences and +formatting. + +Rules are classified by strength: the keyword is \verb-level-. The +non-terminal items are written in a simplest way: a non-terminal +\verb!<$t:dummy-name:*>! is now just written \verb!$t!. For left or +right associativity, the modifiers \verb!:L! or + \verb!:E! have to be given as in \verb!$t:E!. The expression \verb!$t:L! prints the +ast \verb!$t! with a level strictly lower than the current one. +The expression \verb!$t:E! calls the printer with the same level. Thus, for left +associative operators, the left term must be called with \verb!:E!, and the +right one with \verb!:L!. It is the opposite for the right associative +operators. Non associative operators use \verb!:L! for both sub-terms. + +For instance, the following rules in V6.1 syntax + +\begin{verbatim} +Syntax constr Zplus <<(Zplus $n1 $n2)>> 8 + [<hov 0> "`" <$nn1:"dummy":E> "+" <$n2:"dummy":L> "`" ] + with $nn1 := (ZEXPR $n1) $nn2 := (ZEXPR $n2). + +Syntax constr Zminus <<(Zminus $n1 $n2)>> 8 + [<hov 0> "`" <$nn1:"dummy":E> "-" <$n2:"dummy":L> "`" ] + with $nn1 := (ZEXPR $n1) $nn2 := (ZEXPR $n2). + +Syntax constr Zmult <<(Zmult $n1 $n2)>> 7 + [<hov 0> "`" <$nn1:"dummy":E> "*" <$n2:"dummy":L> "`" ] + with $nn1 := (ZEXPR $n1) $nn2 := (ZEXPR $n2). +\end{verbatim} +are now written +\begin{verbatim} +Syntax constr + + level 8: + Zplus [<<(Zplus $n1 $n2)>>] + -> [ [<hov 0> "`"(ZEXPR $n1):E "+"(ZEXPR $n2):L "`"] ] + | Zminus [<<(Zminus $n1 $n2)>>] + -> [ [<hov 0> "`"(ZEXPR $n1):E "-"(ZEXPR $n2):L "`"] ] + ; + + level 7: + Zmult [<<(Zmult $n1 $n2)>>] + -> [ [<hov 0> "`"(ZEXPR $n1):E "*"(ZEXPR $n2):L "`"] ] + . +\end{verbatim} + +\section{How to use \texttt{SearchIsos}} + +As shown in the overview, \texttt{SearchIsos} is made up of two tools: new +commands integrated in Coq and a separated program. + +\subsection{In the {\Coq} toplevel} + +Under \Coq, \texttt{SearchIsos} is called upon with the following command: + +\begin{tabbing} +\ \ \ \ \=\kill +\>{\tt SearchIsos} {\it term}. +\end{tabbing} + +This command displays the full name (modules, sections and identifiers) of all +the constants, variables, inductive types and constructors of inductive types +of the current context (not necessarily in the specialized +buffers) whose type is equal to {\it term} up to isomorphisms. These +isomorphisms of types are characterized by the contextual part of a theory +which is a generalization of the axiomatization for the typed lambda-calculus +associated with the Closed Cartesian Categories taking into account +polymorphism and dependent types. + +\texttt{SearchIsos} is twined with two other commands which allow to have some +informations about the search time: + +\begin{tabbing} +\ \ \ \ \=\kill +\>{\tt Time}.\\ +\>{\tt UnTime}. +\end{tabbing} + +As expected, these two commands respectively sets and disconnects the Time +Search Display mode. + +The following example shows a possibility of use: + +\begin{coq_eval} +Reset Initial. +\end{coq_eval} +\begin{coq_example} +Time. +Variables A,B:Set. +Hypothesis H0:(x:A)(y:B)(x=x/\y=y). +SearchIsos (b:B)(a:A)(b=b/\a=a). +\end{coq_example} + +For more informations, see the sections 5.6.7, 5.6.8 and 5.6.9 in the Reference +Manual. + +\subsection{In the whole library hierarchy} + +To extend the search to a {\Coq} library, you must use \textsf{Coq\_SearchIsos} +which is an independent tool compared to {\Coq} and can be invoked by the shell +command as follows: + +\begin{tabbing} +\ \ \ \ \=\kill +\>{\tt coqtop -searchisos} +\end{tabbing} + +Under this new toplevel (which contains your {\Coq} library), the three +commands {\tt SearchIsos}, {\tt Time} and {\tt UnTime} (described previously) +are then available and have always the same behavior. + +Likewise, this little sample (about the Euclidean division) shows a possible +request to the standard library of {\Coq}: + +\begin{verbatim} +Coq_SearchIsos < Time. + +Coq_SearchIsos < SearchIsos (b,a:nat)(gt b O) +Coq_SearchIsos < ->{q:nat&{r:nat|a=(plus (mult q b) r)/\(gt b r)}}. +#Div#--* [div1 : (b:nat)(gt b (0))->(a:nat)(diveucl a b)] +#Div#--* [div2 : (b:nat)(gt b (0))->(a:nat)(diveucl a b)] +#Euclid_proof#--* [eucl_dev : (b:nat)(gt b (0))->(a:nat)(diveucl a b)] +#Euclid_proof#--* [quotient : +(b:nat) + (gt b (0)) + ->(a:nat){q:nat | (EX r:nat | a=(plus (mult q b) r)/\(gt b r))}] +#Euclid_proof#--* [modulo : +(b:nat) + (gt b (0)) + ->(a:nat){r:nat | (EX q:nat | a=(plus (mult q b) r)/\(gt b r))}] +Finished transaction in 4 secs (2.27u,0s) +\end{verbatim} + +For more informations about \textsf{Coq\_SearchIsos}, see the section 15.4 in +the Reference Manual. + +\section{The new reduction functions} \label{reductions} + +\subsection{\texttt{Cbv}, \texttt{Lazy}} +The usual reduction or conversion tactics are \verb!Red!, \verb!Hnf!, +\verb!Simpl!, \verb!Unfold!, \verb!Change! and \verb!Pattern!. It is +now possible to normalize a goal with a parametric reduction function, +by specifying which of $\beta$,$\delta$ and $\iota$ must be +performed. In the case of $\delta$, a list of identifiers to unfold, +or a list of identifiers not to unfold, may follow. Moreover, two +strategies are available: a call-by-value reduction, efficient for +computations, and a lazy reduction, i.e. a call-by-name strategy with +sharing of reductions. + +To apply a reduction tactic, use one of the two strategies +\texttt{Cbv} for call-by value or \texttt{Lazy} for lazy reduction +applied to one or more ``flags'' designing which reduction to perform +\texttt{Beta} for $\beta$-reduction, \texttt{Iota} for +$\iota$-reduction (reduction of \texttt{Cases}) and \texttt{Delta} for +$\delta$-reduction (expansion of constants). + +The function \verb!Compute! is simply an alias for +\verb!Cbv Beta Delta Iota!. + +The following tactic applies on the current goal, +the $\beta\iota$-reduction, and +$\delta$-reduction of any constants except \verb!minus!, using the +call-by-value strategy. +\begin{verbatim} +Cbv Beta Iota Delta - [ minus ] +\end{verbatim} + +\subsection{\texttt{Fold}} +A specific function \verb!Fold! was designed: +\verb!Fold! takes as argument a list of +terms. These terms are reduced using \verb!Red!, and the result is +replaced by the expanded term. For example, +\begin{coq_example*} +Require Arith. +Lemma ex4 : (n:nat)(le (S O) n)->(le (S n) (plus n n)). +Intros. +\end{coq_example*} +\begin{coq_example} +Fold (plus (1) n). +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\subsection{\texttt{Eval}} + +The reduction may be applied to a given term (not only the goal) with +the vernac command \verb!Eval!. +The syntax is: +\[\texttt{Eval}~ \textit{ReductionFunction}~ \texttt{in}~ +\textit{term}.\] +To compute the reduced value of $t$ using the reduction strategy +\textit{ReductionFunction}. + +It may happen that the term to be +reduced depends on hypothesis introduced in a goal. The default +behavior is that the term is interpreted in the current goal (if +any). \texttt{Eval} can take an extra argument specifying an +alternative goal. + +Here are a few examples of reduction commands: +\begin{coq_example} +Eval Simpl in [n:nat]n=(plus O n). +\end{coq_example} +Simplifies the expression. +\begin{coq_example*} +Lemma ex5 : O=O /\ (x:nat)x=x. +Split; Intros. +\end{coq_example*} +\begin{coq_example} +Eval 2 Lazy Beta Delta [ mult ] Iota in ([n:nat](mult n (plus n x)) (3)). +\end{coq_example} + +$\beta\iota$-reduces the given term and $\delta$-reduces \verb+mult+ in the +context of the second goal. + +\begin{coq_example} +Eval Compute in `18446744073709551616 * 18446744073709551616`. +\end{coq_example} + +Computes $2^{128}$. + +\section{Installation procedure} + +\subsection{Uninstalling Coq} + +\paragraph{Warning} +It is strongly recommended to clean-up the V6.1 Coq library directory +by hand, before you install the new version. +\paragraph{Uninstalling Coq V6.2} +There is a new option to coqtop \texttt{-uninstall} that will remove +the the binaries and the library files of Coq V6.2 on a Unix system. + + +\subsection{OS Issues -- Requirements} + +\subsubsection{Unix users} +You need Objective Caml version 1.06 or 1.07, and Camlp4 version 1.07.2 +to compile the system. Both are available by anonymous ftp +at: + +\bigskip +\verb|ftp://ftp.inria.fr/Projects/Cristal|. +\bigskip + +\noindent +Binary distributions are available for the following architectures: + +\bigskip +\begin{tabular}{l|c|r} +{\bf OS } & {\bf Processor} & {name of the package}\\ +\hline +Linux & 80386 and higher & coq-6.2-linux-i386.tar.gz \\ +Solaris & Sparc & coq-6.2-solaris-sparc.tar.gz\\ +Digital & Alpha & coq-6.2-OSF1.tar.gz\\ +\end{tabular} +\bigskip + +If your configuration is in the above list, you don't need to install +Caml and Camlp4 and to compile the system: +just download the package and install the binaries in the right place. + +\subsubsection{MS Windows users} + +The MS Windows version will be soon available. + +%users will get the 6.2 version at the same time than +%Unix users ! +%A binary distribution is available for Windows 95/NT. Windows 3.1 +%users may run the binaries if they install the Win32s module, freely +%available at \verb|ftp.inria.fr|. + +\section{Credits} + +The new parsing mechanism and the new syntax for extensible grammars +and pretty-printing rules are from Bruno Barras and Daniel de +Rauglaudre. + +The rearrangement of tactics, the extension of \texttt{Tauto}, \texttt{Intros} and +equality tactics, and the tactic definition mechanism are from Eduardo +Gim\'enez. Jean-Christophe Filli\^atre designed and implemented the +tactic \texttt{Refine} and the tactic \texttt{Correctness}. + +Bruno Barras improved the reduction functions and introduced new +uniform commands for reducing a goal or an expression. David Delahaye +designed and implemented {\tt SearchIsos}. + +Patrick Loiseleur introduced syntax rules to +manipulate natural numbers and binary integers expression. +Hugo Herbelin improved the loading mechanism and contributed to a more +user-friendly syntax. + +\end{document} + +% Local Variables: +% mode: LaTeX +% TeX-master: t +% End: + + +% $Id$ + diff --git a/doc/ChangesV6-3.tex b/doc/ChangesV6-3.tex new file mode 100644 index 000000000..8e43a258c --- /dev/null +++ b/doc/ChangesV6-3.tex @@ -0,0 +1,302 @@ +\documentclass[11pt]{article} +\usepackage[latin1]{inputenc} +\usepackage[T1]{fontenc} + +\input{./title} +\input{./macros} + +\begin{document} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Changes 6.2 ===> 6.3 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\shorttitle{Changes from {\Coq} V6.2 to {\Coq} V6.3} + +This document describes the main differences between Coq V6.2 and +V6.3. This new version of Coq is characterized by new tactics and a +more flexible guard condition in fixpoints definitions. +We refer to the reference manual +for a more precise description of the new features. + +%See the ASCII file \texttt{CHANGES} available by FTP with \Coq\ for +%the minor changes of the bug-fix releases 6.2.1 and 6.2.2. + + +\section{Changes overview} + +\subsection{New Tactics} + + \begin{itemize} + + \item The \texttt{AutoRewrite} tactic uses a set of theorems + as rewrite rules that are applied sequentially in order to + solve the goal. This tactic is still experimental and subject to changes. + + \item \texttt{First} and \texttt{Solve} are two tacticals which + apply to a sequence of + tactics written \texttt{[ \textit{tac}$_1$ | ... | + \textit{tac}$_n$ ]}. + \texttt{First} applies the first tactic in the given list + which does not fail while + \texttt{Solve} applies the first tactic in the list + which completely solves the goal. + + \item \texttt{Quote} this new tactic does automatic inversion of + interpretation function for people using Barengregt's so-called + `2-level approach'. See examples in \texttt{theories/DEMOS/DemoQuote.v}. + + \item \texttt{Change} \textit{term} \texttt{in} \textit{hyp} is now + available. + + \item \texttt{Move} \textit{hyp} \texttt{after} \textit{hyp} allows + to reorder the hypotheses of the local context. + + \end{itemize} + +\subsection{Changes in existing tactics} + + \begin{itemize} + + \item \texttt{Intro} or \texttt{Intros} with explicit names + will force an head reduction of the goal in case it does not start + with a product. \\ + +\texttt{Intro} or \texttt{Intros} without explicit names + generate automatically names for the hypothesis or + variable to be introduced. The algorithm to generate these names + has been slightly changed, this may be a source of incompatibility in the + proofs script. + + The new variant \texttt{Intro \textit{ident} after \textit{hyp}} allows to + tell the place where an hypothesis is introduced in the context. + + \item \texttt{Auto} the structure of the hints databases for the Auto + tactic was changed in version V6.2.3. + In version V6.3, the following new features were added to Auto~: + \begin{itemize} + \item \texttt{Print} \textit{HintDbname} prints out the contents of + a the hint database \textit{HintDbname}; + \item \texttt{Constructors} \textit{Indname} is a new hint + tactic which is equivalent to introduce the \texttt{Resolve} + hint tactic for each + constructor of the \textit{Indname} inductive definition. + \end{itemize} + + \item \texttt{Induction} \textit{var} now also performs induction on + a variable \textit{var} of the local context. This extension is + more ``user-friendly'' in the sense it generalizes automatically + above the other hypotheses dependent on the original variable. It + does not duplicate any longer the name of the variable to which it + applies. It should avantageously replaces "Elim" on an + hypothesis/variable or a typical sequence "Generalize" followed by + "Induction" on the generalized variable. But this extension is + experimental and susceptible of change in next releases. + + \item \texttt{Let} \textit{ident} \texttt{:=} \textit{term} + \texttt{in} \textit{occurlist} \textit{hyps} replaces the given + occurrences of \texttt{term} in the hypotheses \textit{hyps} (or in + the goal) by the variable \textit{ident} and keep the equality + \textit{ident=term} in the context. This is actually a variant of + \texttt{Generalize} which keeps track of the original term. As the + new \texttt{Induction} to which it can be combined, it is susceptible + of change in next releases. + + \item The \texttt{Ring} tactic has been extended and + works now also when the ring is in the \Type{} sort. + + \item The tactic \texttt{Correctness} has been improved. + \end{itemize} + +\subsection{New toplevel commands} + +\begin{description} + +\item[\texttt{Time}] Any vernacular command (including invocation of + tactics) can be prefixed by the word \texttt{Time}; then the time + spent is printed after having executed the command. For example : + \texttt{Time Save.} or \texttt{Time Omega.} + +\item[\texttt{Focus} $n$] It is now possible to focus on a specific + goal using the command \texttt{Focus} $n$, with $n$ being the + range of the selected subgoal. All the tactics will be applied to + this goal and only the subgoals inherited from the selected goal + are displayed. When the subgoal is completed, the message + \texttt{"Subtree proved"} is printed out then the focus goes back + to the initial goal and the corresponding remaining subgoals are + printed out. The focus commands are reseted by the + \texttt{Undo} command or \texttt{Unfocus}. \texttt{Focus} + without argument keeps its old meaning to only disply the first + subgoal. + +\item[Evaluation in Definition] It is now possible to apply a + reduction function to a term inside a definition. Just replace the + term to be defined by + \[ \texttt{Eval}~ \textit{reduction-function}~ \texttt{in}~ + \textit{term}\] + at the right hand side of the \texttt{:=} sign in a definition. + + \end{description} + +\subsection{Language extensions} + \begin{description} + \item[Type reconstruction] The algorithm to solve incomplete + information in terms has been improved. In particular + question marks can be put + in place of the type of universally quantified variables. + \item[Guarded fixpoints] The condition for well-formed + fixpoints has been extended, it is now possible to define + structural fixpoints for positive inductive definitions with + nested recursion (like \texttt{Inductive term : Set := cons : (list term)->term}) + \end{description} + +\subsection{Libraries} + + \begin{description} + + \item[Reals] The library of real numbers has been extended and + obeys to the same naming convention than + ARITH and ZARITH: addition is \texttt{Rplus}, theorems stating commutativity are + postfixed by \texttt{\_sym} like \texttt{plus\_sym}, + \texttt{Rmult\_sym}, etc. The tactic \texttt{Ring} has been + instantiated on the reals; one can use it to normalize polynomial + expressions over the reals. + +The library \texttt{Reals} + has been completed by a definition of limit, derivative + and by others properties and functions. +\end{description} + + +\subsection{Documentation} + +The documentation includes now an index of errors. + +\section{Incompatibilities} + + You could have to modify your vernacular source for the following + reasons: + + \begin{itemize} + + \item Some names of variables have changed. Typically, a sequence + "Generalize n; Induction n" should become a "Generalize n; Induction n0", + or better, simply "Induction n" since Induction now works with + hypotheses of the context and generalizes automatically. + + \item In the library ZArith, "Zinv" has been renamed as "Zopp", in + order to be coherent with the Reals library. Theorems whose name + includes "Zinv" have been renamed too. A global search-and-replace + of "Zinv" by "Zopp" should be sufficient to update user's + developments. + + \item In the library Reals, some names has been changed. + In the file README of the library, there is a script which can be + used to update user's developments. + + \item The definition of Exists has changed in LISTS/Streams. + + \end{itemize} + +\section{New contributions} +We integrated new contributions : +\begin{description} +\item[Finite sets and graphs] +This contribution is due to J. Goubault-Larrecq from Dyade + (INRIA-Bull). It contains a +development of finite sets implemented efficiently +as trees indexed by binary numbers. This representation is used to +implement graphs corresponding to arithmetic formulas and prove the +correctness of a decision procedure testing the satisfiability of +formula by detecting cycles of positive weigth in the graph +\item[$\pi$-calculus] A development of $\pi$-calculus due to +I. Scagnetto from University of Udine. +\item[The three gap theorem] A Proof of the Three Gap Theorem + (Steinhaus Conjecture) by M. Mayero from INRIA Rocquencourt. +\item[Floating point numbers] An axiomatisation of the IEEE 754 +norm for Floating point numbers done by P. Loiseleur fron LRI Orsay. +\item[Algebra] Basic notions of algebra designed by L. Pottier from + INRIA Sophia-Antipolis. +\item[Heapsort] A proof of an imperative version of the + Heapsort sorting algorithm developed by J-C. Filli\^atre from +LRI Orsay. + +\end{description} + +\section{Installation procedure} + +\subsection{Uninstalling Coq} + +\paragraph{Warning} +It is strongly recommended to clean-up the V6.2 Coq library directory +before you install the new version. +Use the option to coqtop \texttt{-uninstall} that will remove +the binaries and the library files of Coq V6.2 on a Unix system. + +\subsection{OS Issues -- Requirements} + +\subsubsection{Unix users} +You need Objective Caml version 2.01 or 2.02, and the corresponding +Camlp4 version to compile the system. Both are available by anonymous ftp +at: \\ +\verb|ftp://ftp.inria.fr/Projects/Cristal|. +\bigskip + +\noindent +Binary distributions are available for the following architectures: + +\bigskip +\begin{tabular}{l|c|r} +{\bf OS } & {\bf Processor} & {name of the package}\\ +\hline +Linux & 80386 and higher & coq-6.3-linux-i386.tar.gz \\ +Solaris & Sparc & coq-6.3-solaris-sparc.tar.gz\\ +Digital & Alpha & coq-6.3-OSF1.tar.gz\\ +\end{tabular} +\bigskip + +If your configuration is in the above list, you don't need to install +Caml and Camlp4 and to compile the system: +just download the package and install the binaries in the right place. + +\subsubsection{MS Windows users} + +A binary distribution is available for PC under MS Windows 95/98/NT. +The package is named coq-6.3-win.zip. + +For installation information see the +files INSTALL.win and README.win. + + +%users will get the 6.2 version at the same time than +%Unix users ! +%A binary distribution is available for Windows 95/NT. Windows 3.1 +%users may run the binaries if they install the Win32s module, freely +%available at \verb|ftp.inria.fr|. + +\section{Credits} +B. Barras extended the unification algorithm to complete partial terms +and solved various tricky bugs related to universes.\\ +D. Delahaye developed the \texttt{AutoRewrite} tactic. He also designed the new +behavior of \texttt{Intro} and provided the tacticals \texttt{First} and +\texttt{Solve}.\\ +J.-C. Filli\^atre developed the \texttt{Correctness} tactic.\\ +E. Gim\'enez extended the guard condition in fixpoints.\\ +H. Herbelin designed the new syntax for definitions and extended the +\texttt{Induction} tactic.\\ +P. Loiseleur developed the \texttt{Quote} tactic and +the new design of the \texttt{Auto} +tactic, he also introduced the index of +errors in the documentation.\\ +C. Paulin wrote the \texttt{Focus} command and introduced +the reduction functions in definitions, this last feature +was proposed by J.-F. Monin from CNET Lannion. +\end{document} + +% Local Variables: +% mode: LaTeX +% TeX-master: t +% End: + + +% $Id$ + diff --git a/doc/Coercion.tex b/doc/Coercion.tex new file mode 100644 index 000000000..009d524ab --- /dev/null +++ b/doc/Coercion.tex @@ -0,0 +1,436 @@ +\achapter{Implicit Coercions} +\aauthor{Amokrane Saïbi} + +\label{Coercions-full} +\index{Coercions!presentation} + +\asection{General Presentation} + +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 $(f~a)$ where $f:(x:A)B$ and $a:A'$ when $A'$ can + be seen in some sense as a subtype of $A$. +\item $x:A$ when $A$ is not a type, but can be seen in + a certain sense as a type: set, group, category etc. +\item $(f~a)$ when $f$ is not a function, but can be seen in a certain sense + as a function: bijection, functor, any structure morphism etc. +\end{itemize} + +\asection{Classes} +\index{Coercions!classes} + A class with $n$ parameters is any defined name with a type +$(x_1:A_1)..(x_n:A_n)s$ where $s$ is a sort. Thus a class with +parameters is considered as a single class and not as a family of +classes. An object of a class $C$ is any term of type $(C~t_1 +.. t_n)$. In addition to these user-classes, we have two abstract +classes: + +\begin{itemize} +\item {\tt SORTCLASS}, the class of sorts; + its objects are the terms whose type is a sort. +\item {\tt FUNCLASS}, the class of functions; + its objects are all the terms with a functional + type, i.e. of form $(x:A)B$. +\end{itemize} + +\asection{Coercions} +\index{Coercions!FUNCLASS} +\index{Coercions!SORTCLASS} + A name $f$ can be declared as a coercion between a source user-class +$C$ with $n$ parameters and a target class $D$ if one of these +conditions holds: + +\begin{itemize} +\item $D$ is a user-class, then the type of $f$ must have the form + $(x_1:A_1)..(x_n:A_n)(y:(C~x_1..x_n)) (D~u_1..u_m)$ where $m$ + is the number of parameters of $D$. +\item $D$ is {\tt FUNCLASS}, then the type of $f$ must have the form + $(x_1:A_1)..(x_n:A_n)(y:(C~x_1..x_n))(x:A)B$. +\item $D$ is {\tt SORTCLASS}, then the type of $f$ must have the form + $(x_1:A_1)..(x_n:A_n)(y:(C~x_1..x_n))s$. +\end{itemize} + +We then write $f:C \mbox{\texttt{>->}} D$. The restriction on the type +of coercions is called {\em the uniform inheritance condition}. +Remark that the abstract classes {\tt FUNCLASS} and {\tt SORTCLASS} +cannot be source classes. + + To coerce an object $t:(C~t_1..t_n)$ of $C$ towards $D$, we have to +apply the coercion $f$ to it; the obtained term $(f~t_1..t_n~t)$ is +then an object of $D$. + +\asubsection{Identity Coercions} +\index{Coercions!identity} + + Identity coercions are special cases of coercions used to go around +the uniform inheritance condition. Let $C$ and $D$ be two classes +with respectively $n$ and $m$ parameters and +$f:(x_1:T_1)..(x_k:T_k)(y:(C~u_1..u_n))(D~v_1..v_m)$ a function which +does not verify the uniform inheritance condition. To declare $f$ as +coercion, one has first to declare a subclass $C'$ of $C$: + +$$C' := [x_1:T_1]..[x_k:T_k](C~u_1..u_n)$$ + +\noindent We then define an {\em identity coercion} between $C'$ and $C$: +\begin{eqnarray*} +Id\_C'\_C & := & [x_1:T_1]..[x_k:T_k][y:(C'~x_1..x_k)]\\ + & & (y::(C~u_1..u_n)) +\end{eqnarray*} + +We can now declare $f$ as coercion from $C'$ to $D$, since we can +``cast'' its type as +$(x_1:T_1)..(x_k:T_k)(y:(C'~x_1..x_k))(D~v_1..v_m)$.\\ The identity +coercions have a special status: to coerce an object $t:(C'~t_1..t_k)$ +of $C'$ towards $C$, we have not to insert explicitly $Id\_C'\_C$ +since $(Id\_C'\_C~t_1..t_k~t)$ is convertible with $t$. However we +``rewrite'' the type of $t$ to become an object of $C$; in this case, +it becomes $(C~u_1^*..u_k^*)$ where each $u_i^*$ is the result of the +substitution in $u_i$ of the variables $x_j$ by $t_j$. + + +\asection{Inheritance Graph} +\index{Coercions!inheritance graph} +Coercions form an inheritance graph with classes as nodes. We call +{\em path coercion} an ordered list of coercions between two nodes of +the graph. A class $C$ is said to be a subclass of $D$ if there is a +coercion path in the graph from $C$ to $D$; we also say that $C$ +inherits from $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 oldest one is {\em valid} and the others are ignored. So the order +of declaration of coercions is important. + +We extend notations for coercions to path coercions. For instance +$[f_1;..;f_k]:C \mbox{\texttt{>->}} D$ is the coercion path composed +by the coercions $f_1..f_k$. The application of a path-coercion to a +term consists of the successive application of its coercions. + +\asection{Commands} + +\asubsection{\tt Class {\ident}.}\comindex{Class} +Declares the name {\ident} as a new class. + +\begin{ErrMsgs} +\item {\ident} \errindex{not declared} +\item {\ident} \errindex{is already a class} +\item \errindex{Type of {\ident} does not end with a sort} +\end{ErrMsgs} + +\asubsection{\tt Class Local {\ident}.} +Declares the name {\ident} as a new local class to the current section. + +\asubsection{\tt Coercion {\ident} : {\ident$_1$} >-> {\ident$_2$}.} +\comindex{Coercion} + +Declares the name {\ident} as a coercion between {\ident$_1$} and +{\ident$_2$}. The classes {\ident$_1$} and {\ident$_2$} are first +declared if necessary. + +\begin{ErrMsgs} +\item {\ident} \errindex{not declared} +\item {\ident} \errindex{is already a coercion} +\item \errindex{FUNCLASS cannot be a source class} +\item \errindex{SORTCLASS cannot be a source class} +\item \errindex{Does not correspond to a coercion} \\ + {\ident} is not a function. +\item \errindex{We do not find the source class {\ident$_1$}} +\item {\ident} \errindex{does not respect the inheritance uniform condition} +\item \errindex{The target class does not correspond to {\ident$_2$}} +\end{ErrMsgs} + + When the coercion {\ident} is added to the inheritance graph, non +valid path coercions are ignored; they are signaled by a warning. +\\[0.3cm] +\noindent {\bf Warning :} +\begin{enumerate} +\item \begin{tabbing} +{\tt Ambiguous paths: }\= $[f_1^1;..;f_{n_1}^1] : C_1\mbox{\tt >->}D_1$\\ + \> ... \\ + \>$[f_1^m;..;f_{n_m}^m] : C_m\mbox{\tt >->}D_m$ + \end{tabbing} +\end{enumerate} + +\asubsection{\tt Coercion Local {\ident}:{\ident$_1$} >-> +{\ident$_2$}.} + +Declares the name {\ident} as a local coercion to the current section. + + +\asubsection{\tt Identity Coercion {\ident}:{\ident$_1$} >-> {\ident$_2$}.} + +We check that {\ident$_1$} is a constant with a value of the form +$[x_1:T_1]..[x_n:T_n](\mbox{\ident}_2~t_1..t_m)$ where $m$ is the +number of parameters of \ident$_2$. Then we define an identity +function with the type +$(x_1:T_1)..(x_n:T_n)(y:(\mbox{\ident}_1~x_1..x_n)) +({\mbox{\ident}_2}~t_1..t_m)$, and we declare it as an identity +coercion between {\ident$_1$} and {\ident$_2$}. + +\begin{ErrMsgs} +\item \errindex{Clash with previous constant {\ident}} +\item {\ident$_1$} \errindex{must be a transparent constant} +\end{ErrMsgs} + +\asubsection +{\tt Identity Coercion Local {\ident}:{\ident$_1$} >-> {\ident$_2$}.} + +Declares the name {\ident} as a local identity coercion to the current section. + +\asubsection{\tt Print Classes.} +\comindex{Print Classes} +Print the list of declared classes in the current context. + +\asubsection{\tt Print Coercions.} +\comindex{Print Coercions} +Print the list of declared coercions in the current context. + +\asubsection{\tt Print Graph.} +\comindex{Print Graph} +Print the list of valid path coercions in the current context. + +\asection{Coercions and Pretty-Printing} + + To every declared coercion $f$, we automatically define an +associated pretty-printing rule, also named $f$, to hide the coercion +applications. Thus $(f~t_1..t_n~t)$ is printed as $t$ where $n$ is the +number of parameters of the source class of $f$. The user can change +this behavior just by overwriting the rule $f$ by a new one with the +same name (see chapter~\ref{Addoc-syntax} for more details about +pretty-printing rules). If $f$ is a coercion to {\tt FUNCLASS}, +another pretty-printing rule called $f1$ is also generated. This last +rule prints $(f~t_1..t_n~t_{n+1}..t_m)$ as $(f~t_{n+1}..t_m)$. + + In the following examples, we changed the coercion pretty-printing +rules to show the inserted coercions. + + +\asection{Inheritance Mechanism -- Examples} + + There are three situations: + +\begin{itemize} +\item $(f~a)$ is ill-typed where $f:(x:A)B$ and $a:A'$. If there is a + path coercion between $A'$ and $A$, $(f~a)$ is transformed into + $(f~a')$ where $a'$ is the result of the application of this + path coercion to $a$. + +%\begin{\small} +\begin{coq_example} +Variables C:nat->Set; D:nat->bool->Set; E:bool->Set. +Variable f : (n:nat)(C n) -> (D (S n) true). +Coercion f : C >-> D. +Variable g : (n:nat)(b:bool)(D n b) -> (E b). +Coercion g : D >-> E. +Variable c : (C O). +Variable T : (E true) -> nat. +Check (T c). +\end{coq_example} +%\end{small} + +We give now an example using identity coercions. + +%\begin{small} +\begin{coq_example} +Definition D' := [b:bool](D (S O) b). +Identity Coercion IdD'D : D' >-> D. +Print IdD'D. +Variable d' : (D' true). +Check (T d'). +\end{coq_example} +%\end{small} + + + In the case of functional arguments, we use the monotonic rule of +sub-typing. Approximatively, to coerce $t:(x:A)B$ towards $(x:A')B'$, +one have to coerce $A'$ towards $A$ and $B$ towards $B'$. An example +is given below: + +%\begin{small} +\begin{coq_example} +Variables A,B:Set; h:A->B. +Coercion h : A >-> B. +Variable U : (A -> (E true)) -> nat. +Variable t : B -> (C O). +Check (U t). +\end{coq_example} +%\end{small} + + Remark the changes in the result following the modification of the +previous example. + +%\begin{small} +\begin{coq_example} +Variable U' : ((C O) -> B) -> nat. +Variable t' : (E true) -> A. +Check (U' t'). +\end{coq_example} +%\end{small} + +\item An assumption $x:A$ when $A$ is not a type, is ill-typed. It is + replaced by $x:A'$ where $A'$ is the result of the application + to $A$ of the path coercion between the class of $A$ and {\tt + SORTCLASS} if it exists. This case occurs in the abstraction + $[x:A]t$, universal quantification $(x:A)B$, global variables + and parameters of (co-)inductive definitions and functions. In + $(x:A)B$, such a path coercion may be applied to $B$ also if + necessary. + +%\begin{small} +\begin{coq_example} +Variable Graph : Type. +Variable Node : Graph -> Type. +Coercion Node : Graph >-> SORTCLASS. +Variable G : Graph. +Variable Arrows : G -> G -> Type. +Check Arrows. +Variable fg : G -> G. +Check fg. +\end{coq_example} +%\end{small} + + +\item $(f~a)$ is ill-typed because $f:A$ is not a function. The term + $f$ is replaced by the term obtained by applying to $f$ the path + coercion between $A$ and {\tt FUNCLASS} if it exists. + +%\begin{small} +\begin{coq_example} +Variable bij : Set -> Set -> Set. +Variable ap : (A,B:Set)(bij A B) -> A -> B. +Coercion ap : bij >-> FUNCLASS. +Variable b : (bij nat nat). +Check (b O). +\end{coq_example} +%\end{small} + +Let us see the resulting graph of this session. + +%\begin{small} +\begin{coq_example} +Print Graph. +\end{coq_example} +%\end{small} + +\end{itemize} + + +\asection{Classes as Records} +\index{Coercions!and records} +We allow the definition of {\em Structures with Inheritance} (or +classes as records) by extending the existing {\tt Record} macro +(see section~\ref{Record}). Its new syntax is: + +\begin{center} +\begin{tabular}{l} +{\tt Record \zeroone{>}{\ident} [ {\params} ] : {\sort} := \zeroone{\ident$_0$} \verb+{+} \\ +~~~~\begin{tabular}{l} + {\tt \ident$_1$ $[$:$|$:>$]$ \term$_1$ ;} \\ + ... \\ + {\tt \ident$_n$ $[$:$|$:>$]$ \term$_n$ \verb+}+. } + \end{tabular} +\end{tabular} +\end{center} +The identifier {\ident} is the name of the defined record and {\sort} +is its type. The identifier {\ident$_0$} is the name of its +constructor. The identifiers {\ident$_1$}, .., {\ident$_n$} are the +names of its fields and {\term$_1$}, .., {\term$_n$} their respective +types. The alternative {\tt $[$:$|$:>$]$} is ``{\tt :}'' or ``{\tt +:>}''. If {\tt {\ident$_i$}:>{\term$_i$}}, then {\ident$_i$} is +automatically declared as coercion from {\ident} to the class of +{\term$_i$}. Remark that {\ident$_i$} always verifies the uniform +inheritance condition. The keyword +{\tt Structure}\comindex{Structure} is a synonym of {\tt +Record}. + + +\asection{Coercions and Sections} +\index{Coercions!and sections} + The inheritance mechanism is compatible with the section +mechanism. The global classes and coercions defined inside a section +are redefined after its closing, using their new value and new +type. The classes and coercions which are local to the section are +simply forgotten (no warning message is printed). +Coercions with a local source class or a local target class, and +coercions which do no more verify the uniform inheritance condition +are also forgotten. + +\asection{Examples} + +\begin{itemize} +\item Coercion between inductive types + +\begin{coq_example} +Definition bool_in_nat := [b:bool]if b then O else (S O). +Coercion bool_in_nat : bool >-> nat. +Check O=true. +\end{coq_example} + +\Warning +\item \verb|Check true=O.| fails. This is ``normal'' behaviour of +coercions. To validate \verb|true=O|, the coercion is searched from +\verb=nat= to \verb=bool=. There is no one. + +\item Coercion to a sort + +\begin{coq_eval} +Reset Graph. +\end{coq_eval} +\begin{coq_example} +Variable Graph : Type. +Variable Node : Graph -> Type. +Coercion Node : Graph >-> SORTCLASS. +Variable G : Graph. +Variable Arrows : G -> G -> Type. +Check Arrows. +Variable fg : G -> G. +Check fg. +\end{coq_example} + +\item Coercion to a function + +\begin{coq_example} +Variable bij : Set -> Set -> Set. +Variable ap : (A,B:Set)(bij A B) -> A -> B. +Coercion ap : bij >-> FUNCLASS. +Variable b : (bij nat nat). +Check (b O). +\end{coq_example} + +\item Transitivity of coercion +\begin{coq_eval} +Reset C. +\end{coq_eval} +\begin{coq_example} +Variables C : nat -> Set; D : nat -> bool -> Set; E : bool -> Set. +Variable f : (n:nat)(C n) -> (D (S n) true). +Coercion f : C >-> D. +Variable g : (n:nat)(b:bool)(D n b) -> (E b). +Coercion g : D >-> E. +Variable c : (C O). +Variable T : (E true) -> nat. +Check (T c). +\end{coq_example} + +\item Identity coercion + +\begin{coq_example} +Definition D' := [b:bool](D (S O) b). +Identity Coercion IdD'D : D' >-> D. +Print IdD'D. +Variable d' : (D' true). +Check (T d'). +\end{coq_example} + +\end{itemize} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/Extraction.tex b/doc/Extraction.tex new file mode 100755 index 000000000..cb9949d97 --- /dev/null +++ b/doc/Extraction.tex @@ -0,0 +1,557 @@ +\achapter{Execution of extracted programs in Caml and Haskell} +\label{CamlHaskellExtraction} +\aauthor{Benjamin Werner and Jean-Christophe Filliâtre} +\index{Extraction} + +It is possible to use \Coq\ to build certified and relatively +efficient programs, extracting them from the proofs of their +specifications. The extracted objects are terms of \FW, and can be +obtained at the \Coq\ toplevel with the command {\tt Extraction} +(see \ref{Extraction}). + +We present here a \Coq\ module, {\tt Extraction}, which translates the +extracted terms to ML dialects, namely Caml Light, Objective Caml and +Haskell. In the following, we will not refer to a particular dialect +when possible and ``ML'' will be used to refer to any of the target +dialects. + +One builds effective programs in an \FW\ toplevel (actually the \Coq\ +toplevel) which contains the extracted objects and in which one can +import ML objects. Indeed, in order to instantiate and realize \Coq\ +type and term variables, it is possible to import ML +objects in the \FW\ toplevel, as inductive types or axioms. + +\Rem +The current mechanism of extraction of effective programs +from \Coq\ proofs slightly differs from the one in the versions of +\Coq\ anterior to the version V5.8. In these versions, there were an +explicit toplevel for the language {\sf Fml}. Moreover, it was not +possible to import ML objects in this {\sf Fml} toplevel. + + +%\section{Extraction facilities} +% +%(* TO DO *) +% + +\medskip +In the first part of this document we describe the commands of the +{\tt Extraction} module, and we give some examples in the second part. + + +\asection{The {\tt Extraction} module} +\label{Extraction} + +This section explains how to import ML objects, to realize axioms and +finally to generate ML code from the extracted programs of \FW. + +These features do not belong to the core system, and appear as an +independent module called {\tt Extraction.v} (which is compiled during the +installation of the system). So the first thing to do is to load this +module: + +\begin{coq_example*} +Require Extraction. +\end{coq_example*} + +\asubsection{Generating executable ML code} +\comindex{Write Caml File} +\comindex{Write CamlLight File} +\comindex{Write Haskell File} +The \Coq\ commands to generate ML code are: +\begin{center}\begin{tabular}{ll} + {\tt Write Caml File "\str" [ \ident$_1$ \dots\ \ident$_n$ ] + {\it options}.} + & ({\em for Objective Caml\/}) \\ + {\tt Write CamlLight File "\str" [ \ident$_1$ \dots\ \ident$_n$ ] + {\it options}.} & \\ + {\tt Write Haskell File "\str" [ \ident$_1$ \dots\ \ident$_n$ ] + {\it options}.} & \\ +\end{tabular}\end{center} +where \str\ is the name given to the file to be produced (the suffix +{\tt .ml} is added if necessary), and \ident$_1$ \dots\ \ident$_n$ the +names of the constants to be extracted. This list does not need to be +exhaustive: it is automatically completed into a complete and minimal +environment. Remaining axioms are translated into exceptions, and a +warning is printed in that case. In particular, this will be the case +for {\tt False\_rec}. (We will see below how to realize axioms). + +\paragraph{Optimizations.} +Since Caml Light and Objective Caml are strict languages, 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 an optimization routine will be +called each time the user want to generate Caml programs. Essentially, +it performs constants expansions and reductions. Therefore some +constants will not appear in the resulting Caml program (A warning is +printed for each such constant). To avoid this, just put the constant +name in the previous list \ident$_1$ \dots\ \ident$_n$ and it will not +be expanded. Moreover, three options allow the user to control the +expansion strategy : +\begin{description} + \item[\texttt{noopt}] : specifies not to do any optimization. + \item[\texttt{exact}] : specifies to extract exactly the given + objects (no recursivity). + \item[\texttt{expand [ \ident$_1$ \dots\ \ident$_n$ ]}] : + forces the expansion of the constants \ident$_1$ \dots\ \ident$_n$ + (when it is possible). +\end{description} + + +\asubsection{Realizing axioms} +\comindex{Link} + +It is possible to assume some axioms while developing a proof. Since +these axioms can be any kind of proposition or object 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 program (an \FW\ term actually) corresponds to a given \Coq\ +axiom. The command is {\tt Link} and the syntax: +$$\mbox{\tt Link \ident\ := Fwterm.}$$ +where \ident\ is the name of the axiom to realize and Fwterm\ the +term which realizes it. The system checks that this term has the same +type as the axiom \ident, and returns an error if not. This command +attaches a body to an axiom, and can be seen as a transformation of an +axiom into a constant. + +These semantical attachments have to be done {\em before} generating +the ML code. All type variables must be realized, and term variables +which are not realized will be translated into exceptions. + +\Example Let us illustrate this feature on a small +example. Assume that you have a type variable {\tt A} of type \Set: + +\begin{coq_example*} +Parameter A : Set. +\end{coq_example*} + +and that your specification proof assumes that there is an order +relation {\em inf} over that type (which has no computational +content), and that this relation is total and decidable: + +\begin{coq_example*} +Parameter inf : A -> A -> Prop. +Axiom inf_total : (x,y:A) {(inf x y)}+{(inf y x)}. +\end{coq_example*} + +Now suppose that we want to use this specification proof on natural +numbers; this means {\tt A} has to be instantiated by {\tt nat} +and the axiom {\tt inf\_total} will be realized, for instance, using the +order relation {\tt le} on that type and the decidability lemma +{\tt le\_lt\_dec}. Here is how to proceed: + +\begin{coq_example*} +Require Compare_dec. +\end{coq_example*} +\begin{coq_example} +Link A := nat. +Link inf_total := le_lt_dec. +\end{coq_example} + +\Warning There is no rollback on the command {\tt Link}, that +is the semantical attachments are not forgotten when doing a {\tt Reset}, +or a {\tt Restore State} command. This will be corrected in a later +version. + +\asubsection{Importing ML objects} +In order to realize axioms and to instantiate programs on real data +types, like {\tt int}, {\tt string}, \dots\ or more complicated data +structures, one want to import existing ML objects in the \FW\ +environment. The system provides such features, through the commands +{\tt ML Import Constant} and {\tt ML Import Inductive}. +The first one imports an ML +object as a new axiom and the second one adds a new inductive +definition corresponding to an ML inductive type. + +\paragraph{Warning.} +In the case of Caml dialects, the system would be able to check the +correctness of the imported objects by looking into the interfaces +files of Caml modules ({\tt .mli} files), but this feature is not yet +implemented. So one must be careful when declaring the types of the +imported objects. + +\paragraph{Caml names.} +When referencing a Caml object, you can use strings instead of +identifiers. Therefore you can use the double +underscore notation \verb!module__name! (Caml Light objects) +or the dot notation \verb!module.name! (Objective Caml objects) +to precise the module in which lies the object. + + +\asubsection{Importing inductive types} +\comindex{ML Import Inductive} + +The \Coq\ command to import an ML inductive type is: +$$\mbox{\tt ML Import Inductive \ident\ [\ident$_1$ \dots\ \ident$_n$] == % +{\em <Inductive Definition>}.}$$ +where \ident\ is the name of the ML type, \ident$_1$ \dots\ +\ident$_n$ the name of its constructors, and {\tt\em<Inductive + Definition>} the corresponding \Coq\ inductive definition +(see \ref{Inductive} in the Reference Manual for the syntax of +inductive definitions). + +This command inserts the {\tt\em<Inductive Definition>} in the \FW\ +environment, without elimination principles. From that moment, it is +possible to use that type like any other \FW\ object, and in +particular to use it to realize axioms. The names \ident\ \ident$_1$ +\dots\ \ident$_n$ may be different from the names given in the +inductive definition, in order to avoid clash with previous +constants, and are restored when generating the ML code. + +\noindent One can also import mutual inductive types with the command: +$$\begin{array}{rl} + \mbox{\tt ML Import Inductive} & + \mbox{\tt\ident$_1$ [\ident$^1_1$ \dots\ \ident$^1_{n_1}$]} \\ + & \dots \\ + & \mbox{\tt\ident$_k$ [\ident$^k_1$ \dots\ \ident$^k_{n_k}$]} \\ + & \qquad \mbox{\tt== {\em<Mutual Inductive Definition>}.} + \end{array}$$ %$$ + +\begin{Examples} +\item Let us show for instance how to import the + type {\tt bool} of Caml Light booleans: + +\begin{coq_example} +ML Import Inductive bool [ true false ] == + Inductive BOOL : Set := TRUE : BOOL + | FALSE : BOOL. +\end{coq_example} + +Here we changed the names because the type {\tt bool} is already +defined in the initial state of \Coq. + + \item Assuming that one defined the mutual inductive types {\tt +tree} and {\tt forest} in a Caml Light module, one can import them +with the command: + +\begin{coq_example} +ML Import Inductive tree [node] forest [empty cons] == + Mutual [A:Set] Inductive + tree : Set := node : A -> (forest A) -> (tree A) + with + forest : Set := empty : (forest A) + | cons : (tree A) -> (forest A) -> (forest A). +\end{coq_example} + + \item One can import the polymorphic type of Caml Light lists with +the command: +\begin{coq_example} +ML Import Inductive list [nil cons] == + Inductive list [A:Set] : Set := nil : (list A) + | cons : A->(list A)->(list A). +\end{coq_example} + +\Rem One would have to re-define {\tt nil} and {\tt cons} at +the top of its program because these constructors have no name in Caml Light. +\end{Examples} + +\asubsection{Importing terms and abstract types} +\comindex{ML Import Constant} + +The other command to import an ML object is: +$$\mbox{\tt ML Import Constant \ident$_{ML}$\ == \ident\ : Fwterm.}$$ +where \ident$_{ML}$\ is the name of the ML object and Fwterm\ its type in +\FW. This command defines an axiom in \FW\ of name \ident\ and type +Fwterm. + +\Example To import the type {\tt int} of Caml Light +integers, and the $<$ binary relation on this type, just do +\begin{coq_example} +ML Import Constant int == int : Set. +ML Import Constant lt_int == lt_int : int -> int -> BOOL. +\end{coq_example} +assuming that the Caml Light type {\tt bool} is already imported (with the +name {\tt BOOL}, as above). + + +\asubsection{Direct use of ML\ objects} +\comindex{Extract Constant} +\comindex{Extract Inductive} + +Sometimes the user do not want to extract \Coq\ objects to new ML code +but wants to use already existing ML objects. For instance, it is the +case for the booleans, which already exist in ML: the user do not want +to extract the \Coq\ inductive type \texttt{bool} to a new type for +booleans, but wants to use the primitive boolean of ML. + +The command \texttt{Extract} fulfills this requirement. +It allows the user to declare constant and inductive types which will not be +extracted but replaced by ML objects. The syntax is the following +$$ +\begin{tabular}{l} + \mbox{\tt Extract Constant \ident\ => \ident'.} \\ + \mbox{\tt Extract Inductive \ident\ + => \ident' [ \ident'$_1$ \dots \ident'$_n$ ].} +\end{tabular} +$$ %$$ +where \ident\/ is the name of the \Coq\ object and the prime identifiers +the name of the corresponding ML objects (the names between brackets +are the names of the constructors). +Mutually recursive types are declared one by one, in any order. + +\Example +Typical examples are the following: +\begin{coq_example} +Extract Inductive unit => unit [ "()" ]. +Extract Inductive bool => bool [ true false ]. +Extract Inductive sumbool => bool [ true false ]. +\end{coq_example} + + +\asubsection{Differences between \Coq\ and ML type systems} + +\subsubsection{ML types that are not \FW\ types} + +Some ML recursive types have no counterpart in the type system of +\Coq, like types using the record construction, or non positive types +like +\begin{verbatim} +# type T = C of T->T;; +\end{verbatim} +In that case, you cannot import those types as inductive types, and +the only way to do is to import them as abstract types (with {\tt ML +Import}) together with the corresponding building and de-structuring +functions (still with {\tt ML Import Constant}). + + +\subsubsection{Programs that are not ML-typable} + +On the contrary, some extracted programs in \FW\ are not typable in +ML. There are in fact two cases which can be problematic: +\begin{itemize} + \item If some part of the program is {\em very} polymorphic, there + may be no ML type for it. In that case the extraction to ML works + all right but the generated code may be refused by the ML + type-checker. A very well known example is the {\em distr-pair} + function: +$$\mbox{\tt +Definition dp := [A,B:Set][x:A][y:B][f:(C:Set)C->C](f A x,f B y). +}$$ +In Caml Light, for instance, the extracted term is +\verb!let dp x y f = pair((f x),(f y))! and has type +$$\mbox{\tt +dp : 'a -> 'a -> ('a -> 'b) -> ('b,'b) prod +}$$ +which is not its original type, but a restriction. + + \item Some definitions of \FW\ may have no counterpart in ML. This + happens when there is a quantification over types inside the type + of a constructor; for example: +$$\mbox{\tt +Inductive anything : Set := dummy : (A:Set)A->anything. +}$$ +which corresponds to the definition of ML dynamics. +\end{itemize} + +The first case is not too problematic: it is still possible to run the +programs by switching off the type-checker during compilation. Unless +you misused the semantical attachment facilities you should never get +any message like ``segmentation fault'' for which the extracted code +would be to blame. To switch off the Caml type-checker, use the +function {\tt obj\_\_magic} which gives the type {\tt 'a} to any +object; but this implies changing a little the extracted code by hand. + +The second case is fatal. If some inductive type cannot be translated +to ML, one has to change the proof (or possibly to ``cheat'' by +some low-level manipulations we would not describe here). + +We have to say, though, that in most ``realistic'' programs, these +problems do not occur. For example all the programs of the library are +accepted by Caml type-checker except {\tt Higman.v}\footnote{Should + you obtain a not ML-typable program out of a self developed example, + we would be interested in seeing it; so please mail us the example at + {\em coq@pauillac.inria.fr}}. + + +\asection{Some examples} + +We present here few examples of extractions, taken from the {\tt +theories} library of \Coq\ (into the {\tt PROGRAMS} directory). We +choose Caml Light as target language, but all can be done in the other +dialects with slight modifications. + + +\asubsection{Euclidean division} + +The file {\tt Euclid\_prog} contains the proof of Euclidean division +(theorem {\tt eucl\_dev}). The natural numbers defined in the example +files are unary integers defined by two constructors $O$ and $S$: +\begin{coq_example*} +Inductive nat : Set := O : nat | S : nat -> nat. +\end{coq_example*} + +To use the proof, we begin by loading the module {\tt Extraction} and the +file into the \Coq\ environment: + +\begin{coq_eval} +Reset Initial. +AddPath "../theories/DEMOS/PROGRAMS". +\end{coq_eval} +\begin{coq_example*} +Require Extraction. +Require Euclid_prog. +\end{coq_example*} + +This module contains a theorem {\tt eucl\_dev}, and its extracted term +is of type {\tt (b:nat)(a:nat) (di\-veucl a b)}, where {\tt diveucl} is a +type for the pair of the quotient and the modulo. +We can now extract this program to Caml Light: + +\begin{coq_example} +Write CamlLight File "euclid" [ eucl_dev ]. +\end{coq_example} + +This produces a file {\tt euclid.ml} containing all the necessary +definitions until {\tt let eucl\_dev = ..}. Let us play the resulting program: + +\begin{verbatim} +# include "euclid";; +# eucl_dev (S (S O)) (S (S (S (S (S O)))));; +- : diveucl = divex (S (S O), S O) +\end{verbatim} +It is easier to test on Caml Light integers: +\begin{verbatim} +# let rec nat_of = function 0 -> O + | n -> S (nat_of (pred n));; +# let rec int_of = function O -> 0 + | S p -> succ (int_of p);; +# let div a b = match eucl_dev (nat_of b) (nat_of a) with + divex(q,r) -> (int_of q, int_of r);; +div : int -> int -> int * int = <fun> +# div 173 15;; +- : int * int = 11, 8 +\end{verbatim} + +\asubsection{Heapsort} + +Let us see a more complicated example. The file {\tt Heap\_prog.v} +contains the proof of an efficient list sorting algorithm described by +Bjerner. Is is an adaptation of the well-known {\em heapsort} +algorithm to functional languages. We first load the files: + +\begin{coq_eval} +Reset Initial. +\end{coq_eval} +\begin{coq_example*} +Require Extraction. +Require Heap_prog. +\end{coq_example*} + +As we saw it above we have to instantiate or realize by hand some of +the \Coq\ variables, which are in this case the type of the elements +to sort ({\tt List\_Dom}, defined in {\tt List.v}) and the +decidability of the order relation ({\tt inf\_total}). We proceed as +in section \ref{Extraction}: + +\begin{coq_example} +ML Import Constant int == int : Set. +Link List_Dom := int. +ML Import Inductive bool [ true false ] == + Inductive BOOL : Set := TRUE : BOOL + | FALSE : BOOL. +ML Import Constant lt_int == lt_int : int->int->BOOL. +Link inf_total := + [x,y:int]Cases (lt_int x y) of + TRUE => left + | FALSE => right + end. +\end{coq_example} + +Then we extract the Caml Light program + +\begin{coq_example} +Write CamlLight File "heapsort" [ heapsort ]. +\end{coq_example} +and test it +\begin{verbatim} + +# include "heapsort";; +# let rec listn = function 0 -> nil + | n -> cons(random__int 10000,listn (pred n));; +# heapsort (listn 10);; +- : list = cons (136, cons (760, cons (1512, cons (2776, cons (3064, +cons (4536, cons (5768, cons (7560, cons (8856, cons (8952, nil)))))))))) +\end{verbatim} + +Some tests on longer lists (100000 elements) show that the program is +quite efficient for Caml code. + +\asubsection{Balanced trees} + +The file {\tt Avl\_prog.v} contains the proof of insertion in binary +balanced trees (AVL). Here we choose to instantiate such trees on the +type {\tt string} of Caml Light (for instance to get efficient +dictionary); as above we must realize the decidability of the order +relation. It gives the following commands: + +\begin{coq_eval} +Reset Initial. +\end{coq_eval} +\begin{coq_example*} +Require Extraction. +Require Avl_prog. +\end{coq_example*} +\begin{coq_eval} +Pwd. +\end{coq_eval} +\begin{coq_example} +ML Import Constant string == string : Set. +ML Import Inductive bool [ true false ] == + Inductive BOOL : Set := TRUE : BOOL + | FALSE : BOOL. +ML Import Constant lt_string == lt_string : string->string->BOOL. +Link a := string. +Link inf_dec := + [x,y:string]Cases (lt_string x y) of + TRUE => left + | FALSE => right + end. +Write CamlLight File "avl" [rot_d rot_g rot_gd insert]. +\end{coq_example} + +Notice that we do not want the constants {\tt rot\_d}, {\tt rot\_g} +and {\tt rot\_gd} to be expanded in the function {\tt insert}, and +that is why we added them in the list of required functions. It makes +the resulting program clearer, even if it becomes less efficient. + +Let us insert random words in an initially empty tree to check that it +remains balanced: +\begin{verbatim} +% camllight +# include "avl";; +# let add a t = match insert a t with + h_eq x -> x + | h_plus x -> x ;; +# let rdmw () = let s = create_string 5 in + for i = 0 to 4 do + set_nth_char s i (char_of_int (97+random__int 26)) + done ; s ;; +# let rec built = function 0 -> nil + | n -> add (rdmw()) (built (pred n));; +# built 10;; +- : abe = node ("ogccy", node ("gmygy", node ("cwqug", node ("cjyrc", nil, ... + + +# let rec size = function + nil -> 0 + | node(_,t1,t2,_) -> 1+(max (size t1) (size t2)) ;; +# let rec check = function + nil -> true + | node(_,a1,a2,_) -> + let t1 = size a1 and t2 =size a2 in + if abs(t1-t2)>1 then false else (check a1) & (check a2) ;; + +# check (built 100);; +- : bool = true +\end{verbatim} + + +\section{Bugs} + +Surely there are still bugs in the {\tt Extraction} module. +You can send your bug reports directly to the author +(at \textsf{Jean-Christophe.Filliatre$@$lri.fr}) or to the \Coq\ +mailing list (at \textsf{coq$@$pauillac.inria.fr}). + +% $Id$ diff --git a/doc/Library.tex b/doc/Library.tex new file mode 100755 index 000000000..bb9ef22c1 --- /dev/null +++ b/doc/Library.tex @@ -0,0 +1,57 @@ +\documentclass[11pt]{article} + +\input{./title} +\input{./macros} +\input{./library/macros} + +\begin{document} + +\coverpage{The standard library}% +{\ } + +\tableofcontents + +\newpage +\section*{The \Coq\ standard library} + +This document is a short description of the \Coq\ standard library. +This library comes with the system as a complement of the core library +(the {\bf INIT} library ; see the Reference Manual for a description +of this library). It provides a set of modules directly available +through the \verb!Require! command. + +The standard library is composed of the following subdirectories: + +\medskip +\begin{tabular}{lp{10cm}} + {\bf LOGIC} & Classical logic and dependent equality \\ + {\bf ARITH} & Basic Peano arithmetic \\ + {\bf ZARITH} & Binary integers \\ + {\bf BOOL} & Booleans (basic functions and results) \\ + {\bf LISTS} & Monomorphic and polymorphic lists (basic functions and + results), Streams (infinite sequences defined with co-inductive + types) \\ + {\bf SETS} & Sets (classical, constructive, finite, infinite, powerset, + etc.) \\ + {\bf RELATIONS} & Relations (definitions and basic results). There is + a subdirectory about well-founded relations ({\bf WELLFOUNDED}) \\ + {\bf SORTING} & Axiomatizations of sorts \\ + {\bf REALS} & Axiomatization of Real Numbers (classical, basic functions + and results, integer part and fractional part, require ZARITH + library) +\end{tabular} +\medskip + +Each of these subdirectories contains a set of modules, whose +specifications ({\sf Gallina} files) have +been roughly, and automatically, pasted in the following pages. There +is also a version of this document in HTML format on the WWW, which +you can access from the \Coq\ home page at +\texttt{http://pauillac.inria.fr/coq/coq-eng.html}. + + +\input{library/libdoc.tex} + +\end{document} + +% $Id$ diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 000000000..611e38d3e --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,273 @@ +# To compile documentation, you need the following tools: +# Dvi: latex (latex2e), bibtex, makeindex, dviselect (package RPM dviutils) +# Ps: dvips, psutils (ftp://ftp.dcs.ed.ac.uk/pub/ajcd/psutils.tar.gz) +# Pdf: pdflatex +# Html: +# - hevea: http://para.inria.fr/~maranget/hevea/ +# - htmlSplit: http://coq.inria.fr/~delahaye +# Rapports INRIA: dviselect, rrkit (par Michel Mauny) + +include ../config + +LATEX=latex +BIBTEX=bibtex +MAKEINDEX=makeindex +PDFLATEX=pdflatex +DOCCOQTOP="../bin/$(ARCH)/coqtop -full -bindir ../bin/$(ARCH)/ -libdir ../" +DOCCOQC=../bin/$(ARCH)/coqc -full -bindir ../bin/$(ARCH)/ -libdir ../ +COQTEX=../bin/$(ARCH)/coq-tex -image $(DOCCOQTOP) -v -sl -small +TEXINPUTS=$(COQTOP)/tools/coq-tex:/usr/local/lib/rrkit/RRINPUTSDIR:.: +ZLIBS=-I ../src/lib/util -I ../src/parsing -I ../src/meta -I ../src/constr \ + -I ../src/typing -I ../src/proofs -I ../src/env -I ../src/tactics \ + -I ../tactics + +INPUTS=./macros.tex ./title.tex ./headers.tex ./Reference-Manual.tex + +LIBFILES=library/Logic.tex library/Datatypes.tex library/Peano.tex \ + library/Wf.tex library/Specif.tex + +REFMANCOQTEXFILES=\ + RefMan-gal.v.tex RefMan-ext.v.tex RefMan-tac.v.tex \ + RefMan-cic.v.tex RefMan-lib.v.tex RefMan-tacex.v.tex \ + RefMan-syn.v.tex RefMan-ppr.v.tex RefMan-tus.v.tex + +COQTEXFILES= Cases.v.tex Coercion.v.tex Extraction.v.tex Program.v.tex\ + Omega.v.tex Natural.v.tex Changes.v.tex Tutorial.v.tex Polynom.v.tex \ + Programs.v.tex + +REFMANFILES= Reference-Manual.tex RefMan-pre.tex RefMan-int.tex \ + RefMan-pro.tex RefMan-oth.tex \ + RefMan-com.tex RefMan-uti.tex RefMan-add.tex \ + $(REFMANCOQTEXFILES) + +REFMAN=Reference-Manual + +#VERSION=V6.3.1 +VERSION=POSITIONNEZ-CETTE-VARIABLE +FTPDOCDIR=/net/pauillac/infosystems/ftp/coq/coq/$(VERSION)/doc +WWWDOCDIR=/net/pauillac/infosystems/www/coq/doc + +FTPDOCS=Changes.dvi.gz Changes.ps.gz \ + Reference-Manual-base.ps.gz Reference-Manual-base.dvi.gz \ + Reference-Manual-addendum.ps.gz Reference-Manual-addendum.dvi.gz\ + Reference-Manual-all.ps.gz Reference-Manual-all.dvi.gz\ + Library.dvi.gz Library.ps.gz\ + Tutorial.dvi.gz Tutorial.ps.gz\ + README all-ps-docs.tar.gz + +FTPHTMLDOCS=doc-html.tar.gz + +######################### +# Principal targets +######################## + +all: demos-programs all-dvi all-pdf + +coq-part: $(REFMANCOQTEXFILES) $(COQTEXFILES) demos-programs library/libdoc.tex + +latex-part: all-dvi + +all-dvi: Tutorial.v.dvi Reference-Manual.dvi Library.dvi Changes.v.dvi + +all-pdf: Tutorial.v.pdf Reference-Manual.pdf Library.pdf Changes.v.pdf + +all-ps: Tutorial.v.ps Reference-Manual.ps Library.ps Changes.v.ps + +all-html: Tutorial.v.html Reference-Manual.html Changes.v.html + + +# dvips et dviselect existent sur loupiac +distrib: + make clean-coq demos-programs + make clean-latex all-dvi all-ps all-pdf compress-latex + make clean-html all-html doc-html.tar.gz html-www + +compress-latex: + sh Reference-Manual.sh + mv -f Reference-Manual.ps Reference-Manual-all.ps + mv -f Tutorial.v.ps Tutorial.ps + mv -f Tutorial.v.dvi Tutorial.dvi + mv -f Reference-Manual.dvi Reference-Manual-all.dvi + mv -f Changes.v.ps Changes.ps + mv -f Changes.v.dvi Changes.dvi + - mv -f Tutorial.v.pdf Tutorial.pdf + - mv -f Changes.v.pdf Changes.pdf + tar cf all-ps-docs.tar Reference-Manual-base.ps \ + Reference-Manual-addendum.ps Changes.ps Tutorial.ps Library.ps + gzip *.ps + gzip *.dvi + gzip *.pdf + gzip all-ps-docs.tar + +Tutorial.v.html: Tutorial.v.tex + hevea ./book-html.sty ./coq-html.sty ./Tutorial.v.tex + +Changes.v.html: Changes.v.tex + hevea ./Changes.v.tex + +Reference-Manual.html: + hevea ./book-html.sty ./coq-html.sty ./Reference-Manual.tex + +doc-html.tar.gz: all-html + - $(MKDIR) coq-docs-html + rm -rf coq-docs-html/* + cp Tutorial.v.html coq-docs-html/tutorial.html + cp Changes.v.html coq-docs-html/changes.html + cp Reference-Manual.html coq-docs-html + (cd coq-docs-html;\ + htmlsplit -N -T "The Coq Proof Assistant Reference Manual"\ + ./Reference-Manual.html; rm ./Reference-Manual.html) + cp cover.html coq-docs-html + tar cf doc-html.tar coq-docs-html + gzip doc-html.tar + +# Pour le site de Coq. +html-www: all-html + - $(MKDIR) www + rm -rf www/* + cp Tutorial.v.html www/tutorial.html + cp Changes.v.html www/changes.html + cp Reference-Manual.html www + (cd www;\ + htmlsplit -N -T "The Coq Proof Assistant Reference Manual"\ + -n ../icons/next.gif -p ../icons/prev.gif -r ../icons/root.gif\ + -s ../icons/sub.gif ./Reference-Manual.html;\ + rm ./Reference-Manual.html) + cp cover.html www + + +clean-refman: + rm -f Reference-Manual.toc Reference-Manual.idx Reference-Manual.atoc\ + Reference-Manual.aux Reference-Manual.bbl Reference-Manual.blg\ + Reference-Manual.ilg Reference-Manual.ind\ + Reference-Manual.tacidx Reference-Manual.tacind\ + Reference-Manual.comidx Reference-Manual.comind\ + Reference-Manual.erridx Reference-Manual.errind\ + Reference-Manual.dvi Reference-Manual.ps\ + Reference-Manual.sh\ + $(REFMANFILES:.tex=.aux) $(REFMANFILES:.tex=.log)\ + $(COQTEXFILES:.tex=.aux) $(COQTEXFILES:.tex=.log) + +clean-latex: clean-refman + rm -f *.dvi *.aux *.log *.bbl *.blg *.ps *.toc *.idx *~ *.ilg *.ind\ + *.dvi.gz *.ps.gz *.pdf *.pdf.gz + +clean-coq: + rm -f *.v.tex avl.ml heapsort.ml euclid.ml library/libdoc.tex *.cm[io] + +clean: clean-coq clean-latex + +clean-html: + rm -f Tutorial.v.html Changes.v.html Reference-Manual.html + +cleanall: clean clean-html + +######################### +# Implicit rules +######################### + +.SUFFIXES: .dvi .tex .v.tex .ps .pdf + +.tex.dvi: + $(LATEX) $< + $(LATEX) $< + +.tex.pdf: + $(PDFLATEX) $< + $(PDFLATEX) $< + +.tex.v.tex: + $(COQTEX) $< + +.dvi.ps: + dvips -o $@ $< + + +########################## +# Dependencies +########################## + +Library.dvi: $(INPUTS) library/libdoc.tex Library.tex +Library.pdf: $(INPUTS) library/libdoc.tex Library.tex + +library/libdoc.tex: + (cd ../theories ; make doc) + +demos-programs: + (cd ../theories/DEMOS/PROGRAMS ; make all) + +Recursive-Definition.v.tex: ./title.tex Recursive-Definition.tex + +Tutorial.v.dvi: ./title.tex Tutorial.tex +Tutorial.v.pdf: ./title.tex Tutorial.tex + +RefMan-ppr.v.tex: ../tactics/eqdecide.cmo + +RefMan-tus.v.tex: ../tactics/EqDecide.vo ../tactics/eqdecide.cmo + +Reference-Manual.ps: Reference-Manual.dvi + +Reference-Manual.dvi: $(INPUTS) $(REFMANFILES) $(COQTEXFILES) biblio.bib + rm -f Reference-Manual.sh + $(LATEX) Reference-Manual + rm Reference-Manual.sh + $(BIBTEX) Reference-Manual + $(LATEX) Reference-Manual + rm Reference-Manual.sh + $(BIBTEX) Reference-Manual + $(LATEX) Reference-Manual + rm Reference-Manual.sh + $(MAKEINDEX) Reference-Manual + $(MAKEINDEX) Reference-Manual.tacidx -o Reference-Manual.tacind + $(MAKEINDEX) Reference-Manual.comidx -o Reference-Manual.comind + $(MAKEINDEX) Reference-Manual.erridx -o Reference-Manual.errind + $(LATEX) Reference-Manual + rm Reference-Manual.sh + $(LATEX) Reference-Manual + +Reference-Manual.pdf: Reference-Manual.dvi + rm -f Reference-Manual.sh + $(PDFLATEX) Reference-Manual.tex + +quick: $(INPUTS) $(REFMANFILES) $(COQTEXFILES) biblio.bib + rm -f Reference-Manual.sh + $(LATEX) Reference-Manual + + +################### +# RT +################### +# Fabrication d'un RT INRIA (utilise rrkit de Michel Mauny) +Reference-Manual-RT.dvi: Reference-Manual.dvi RefMan-cover.tex + dviselect -i Reference-Manual.dvi -o RefMan-body.dvi 3: + $(LATEX) RefMan-cover.tex + set a=`tail -1 Reference-Manual.log`;\ + set a=expr \("$$a" : '.*(\(.*\) pages.*'\) % 2;\ + if test "$$a = 0";\ + then rrkit RefMan-cover.dvi RefMan-body.dvi Reference-Manual-RT.dvi;\ + else rrkit -odd RefMan-cover.dvi RefMan-body.dvi Reference-Manual-RT.dvi;\ + fi + +# Fabrication d'un RT INRIA (utilise rrkit de Michel Mauny) +Tutorial-RT.dvi : Tutorial.v.dvi Tutorial-cover.tex + dviselect -i Tutorial.v.dvi -o Tutorial-body.dvi 3: + $(LATEX) Tutorial-cover.tex + set a=`tail -1 Tutorial.v.log`;\ + set a=expr \("$$a" : '.*(\(.*\) pages.*'\) % 2;\ + if test "$$a = 0";\ + then rrkit Tutorial-cover.dvi Tutorial-body.dvi Tutorial-RT.dvi;\ + else rrkit -odd Tutorial-cover.dvi Tutorial-body.dvi Tutorial-RT.dvi;\ + fi + +################ doc ftp and www installation ############ +doc-ftp-www-install: doc-ftp-install doc-www-install + +doc-ftp-install: + - mkdir $(FTPDOCDIR) + cp $(ALLFTPDOCS) $(FTPHTMLDOCS) $(FTPDOCDIR) + chmod g+w $(FTPDOCDIR)/* + +doc-www-install: + (cd $(WWWDOCDIR); rm -f node*.html main*.html toc.html \ + tutorial.html changes.html cover.html) + cp www/* $(WWWDOCDIR) diff --git a/doc/Natural.tex b/doc/Natural.tex new file mode 100755 index 000000000..69dfab87c --- /dev/null +++ b/doc/Natural.tex @@ -0,0 +1,425 @@ +\achapter{\texttt{Natural} : proofs in natural language} +\aauthor{Yann Coscoy} + +\asection{Introduction} + +\Natural~ is a package allowing the writing of proofs in natural +language. For instance, the proof in \Coq~of the induction principle on pairs +of natural numbers looks like this: + +\begin{coq_example*} +Require Natural. +\end{coq_example*} +\begin{coq_example} +Print nat_double_ind. +\end{coq_example} + +Piping it through the \Natural~pretty-printer gives: + +\comindex{Print Natural} +\begin{coq_example} +Print Natural nat_double_ind. +\end{coq_example} + +\asection{Activating \Natural} + +To enable the printing of proofs in natural language, you should +type under \texttt{coqtop} or \texttt{coqtop -full} the command + +\begin{coq_example*} +Require Natural. +\end{coq_example*} + +By default, proofs are transcripted in english. If you wish to print them +in French, set the French option by + +\comindex{Set Natural} +\begin{coq_example*} +Set Natural French. +\end{coq_example*} + +If you want to go back to English, type in + +\begin{coq_example*} +Set Natural English. +\end{coq_example*} + +Currently, only \verb=French= and \verb=English= are available. + +You may see for example the natural transcription of the proof of +the induction principle on pairs of natural numbers: + +\begin{coq_example*} +Print Natural nat_double_ind. +\end{coq_example*} + +You may also show in natural language the current proof in progress: + +\comindex{Show Natural} +\begin{coq_example} +Goal (n:nat)(le O n). +Induction n. +Show Natural Proof. +\end{coq_example} + +\subsection*{Restrictions} + +For \Natural, a proof is an object of type a proposition (i.e. an +object of type something of type {\tt Prop}). Only proofs are written +in natural language when typing {\tt Print Natural \ident}. All other +objects (the objects of type something which is of type {\tt Set} or +{\tt Type}) are written as usual $\lambda$-terms. + +\asection{Customizing \Natural} + +The transcription of proofs in natural language is mainly a paraphrase of +the formal proofs, but some specific hints in the transcription +can be given. +Three kinds of customization are available. + +\asubsection{Implicit proof steps} + +\subsubsection*{Implicit lemmas} + +Applying a given lemma or theorem \verb=lem1= of statement, say $A +\Rightarrow B$, to an hypothesis, say $H$ (assuming $A$) produces the +following kind of output translation: + +\begin{verbatim} +... +Using lem1 with H we get B. +... +\end{verbatim} + +But sometimes, you may prefer not to see the explicit invocation to +the lemma. You may prefer to see: + +\begin{verbatim} +... +With H we have A. +... +\end{verbatim} + +This is possible by declaring the lemma as implicit. You should type: + +\comindex{Add Natural} +\begin{coq_example*} +Add Natural Implicit lem1. +\end{coq_example*} + +By default, the lemmas \verb=proj1=, \verb=proj2=, \verb=sym_equal= +and \verb=sym_eqT= are declared implicit. To remove a lemma or a theorem +previously declared as implicit, say \verb=lem1=, use the command + +\comindex{Remove Natural} +\begin{coq_example*} +Remove Natural Implicit lem1. +\end{coq_example*} + +To test if the lemma or theorem \verb=lem1= is, or is not, +declared as implicit, type + +\comindex{Test Natural} +\begin{coq_example*} +Test Natural Implicit lem1. +\end{coq_example*} + +\subsubsection*{Implicit proof constructors} + +Let \verb=constr1= be a proof constructor of a given inductive +proposition (or predicate) +\verb=Q= (of type \verb=Prop=). Assume \verb=constr1= proves +\verb=(x:A)(P x)->(Q x)=. Then, applying \verb=constr1= to an hypothesis, +say \verb=H= (assuming \verb=(P a)=) produces the following kind of output: + +\begin{verbatim} +... +By the definition of Q, with H we have (Q a). +... +\end{verbatim} + +But sometimes, you may prefer not to see the explicit invocation to +this constructor. You may prefer to see: + +\begin{verbatim} +... +With H we have (Q a). +... +\end{verbatim} + +This is possible by declaring the constructor as implicit. You should +type, as before: + +\comindex{Add Natural Implicit} +\begin{coq_example*} +Add Natural Implicit constr1. +\end{coq_example*} + +By default, the proposition (or predicate) constructors + +\verb=conj=, \verb=or_introl=, \verb=or_intror=, \verb=ex_intro=, +\verb=exT_intro=, \verb=refl_equal=, \verb=refl_eqT= and \verb=exist= + +\noindent are declared implicit. Note that declaring implicit the +constructor of a datatype (i.e. an inductive type of type \verb=Set=) +has no effect. + +As above, you can remove or test a constant declared implicit. + +\subsubsection*{Implicit inductive constants} + +Let \verb=Ind= be an inductive type (either a proposition (or a +predicate) -- on \verb=Prop= --, or a datatype -- on \verb=Set=). +Suppose the proof proceeds by induction on an hypothesis \verb=h= +proving \verb=Ind= (or more generally \verb=(Ind A1 ... An)=). The +following kind of output is produced: + +\begin{verbatim} +... +With H, we will prove A by induction on the definition of Ind. +Case 1. ... +Case 2. ... +... +\end{verbatim} + +But sometimes, you may prefer not to see the explicit invocation to +\verb=Ind=. You may prefer to see: + +\begin{verbatim} +... +We will prove A by induction on H. +Case 1. ... +Case 2. ... +... +\end{verbatim} + +This is possible by declaring the inductive type as implicit. You should +type, as before: + +\comindex{Add Natural Implicit} +\begin{coq_example*} +Add Natural Implicit Ind. +\end{coq_example*} + +This kind of parameterization works for any inductively defined +proposition (or predicate) or datatype. Especially, it works whatever +the definition is recursive or purely by cases. + +By default, the data type \verb=nat= and the inductive connectives +\verb=and=, \verb=or=, \verb=sig=, \verb=False=, \verb=eq=, +\verb=eqT=, \verb=ex= and \verb=exT= are declared implicit. + +As above, you can remove or test a constant declared implicit. Use +{\tt Remove Natural Contractible $id$} or {\tt Test Natural +Contractible $id$}. + +\asubsection{Contractible proof steps} + +\subsubsection*{Contractible lemmas or constructors} + +Some lemmas, theorems or proof constructors of inductive predicates are +often applied in a row and you obtain an output of this kind: + +\begin{verbatim} +... +Using T with H1 and H2 we get P. + * By H3 we have Q. + Using T with theses results we get R. +... +\end{verbatim} + +where \verb=T=, \verb=H1=, \verb=H2= and \verb=H3= prove statements +of the form \verb=(X,Y:Prop)X->Y->(L X Y)=, \verb=A=, \verb=B= and \verb=C= +respectively (and thus \verb=R= is \verb=(L (L A B) C)=). + +You may obtain a condensed output of the form + +\begin{verbatim} +... +Using T with H1, H2, and H3 we get R. +... +\end{verbatim} + +by declaring \verb=T= as contractible: + +\comindex{Add Natural Contractible} +\begin{coq_example*} +Add Natural Contractible T. +\end{coq_example*} + +By default, the lemmas \verb=proj1=, \verb=proj2= and the proof +constructors \verb=conj=, \verb=or_introl=, \verb=or_intror= are +declared contractible. As for implicit notions, you can remove or +test a lemma or constructor declared contractible. + +\subsubsection*{Contractible induction steps} + +Let \verb=Ind= be an inductive type. When the proof proceeds by +induction in a row, you may obtain an output of this kind: + +\begin{verbatim} +... +We have (Ind A (Ind B C)). +We use definition of Ind in a study in two cases. +Case 1: We have A. +Case 2: We have (Ind B C). + We use definition of Ind in a study of two cases. + Case 2.1: We have B. + Case 2.2: We have C. +... +\end{verbatim} + +You may prefer to see + +\begin{verbatim} +... +We have (Ind A (Ind B C)). +We use definition of Ind in a study in three cases. +Case 1: We have A. +Case 2: We have B. +Case 3: We have C. +... +\end{verbatim} + +This is possible by declaring \verb=Ind= as contractible: + +\begin{coq_example*} +Add Natural Contractible T. +\end{coq_example*} + +By default, only \verb=or= is declared as a contractible inductive +constant. +As for implicit notions, you can remove or test an inductive notion declared +contractible. + +\asubsection{Transparent definitions} + +``Normal'' definitions are all constructions except proofs and proof constructors. + +\subsubsection*{Transparent non inductive normal definitions} + +When using the definition of a non inductive constant, say \verb=D=, the +following kind of output is produced: + +\begin{verbatim} +... +We have proved C which is equivalent to D. +... +\end{verbatim} + +But you may prefer to hide that D comes from the definition of C as +follows: + +\begin{verbatim} +... +We have prove D. +... +\end{verbatim} + +This is possible by declaring \verb=C= as transparent: + +\comindex{Add Natural Transparent} +\begin{coq_example*} +Add Natural Transparent D. +\end{coq_example*} + +By default, only \verb=not= (normally written \verb=~=) is declared as +a non inductive transparent definition. +As for implicit and contractible definitions, you can remove or test a +non inductive definition declared transparent. +Use \texttt{Remove Natural Transparent} \ident or +\texttt{Test Natural Transparent} \ident. + +\subsubsection*{Transparent inductive definitions} + +Let \verb=Ind= be an inductive proposition (more generally: a +predicate \verb=(Ind x1 ... xn)=). Suppose the definition of +\verb=Ind= is non recursive and built with just +one constructor proving something like \verb=A -> B -> Ind=. +When coming back to the definition of \verb=Ind= the +following kind of output is produced: + +\begin{verbatim} +... +Assume Ind (H). + We use H with definition of Ind. + We have A and B. + ... +\end{verbatim} + +When \verb=H= is not used a second time in the proof, you may prefer +to hide that \verb=A= and \verb=B= comes from the definition of +\verb=Ind=. You may prefer to get directly: + +\begin{verbatim} +... +Assume A and B. +... +\end{verbatim} + +This is possible by declaring \verb=Ind= as transparent: + +\begin{coq_example*} +Add Natural Transparent Ind. +\end{coq_example*} + +By default, \verb=and=, \verb=or=, \verb=ex=, \verb=exT=, \verb=sig= +are declared as inductive transparent constants. As for implicit and +contractible constants, you can remove or test an inductive +constant declared transparent. + +As for implicit and contractible constants, you can remove or test an +inductive constant declared transparent. + +\asubsection{Extending the maximal depth of nested text} + +The depth of nested text is limited. To know the current depth, do: + +\comindex{Set Natural Depth} +\begin{coq_example} +Set Natural Depth. +\end{coq_example} + +To change the maximal depth of nested text (for instance to 125) do: + +\begin{coq_example} +Set Natural Depth 125. +\end{coq_example} + +\asubsection{Restoring the default parameterization} + +The command \verb=Set Natural Default= sets back the parameterization tables of +\Natural~ to their default values, as listed in the above sections. +Moreover, the language is set back to English and the max depth of +nested text is set back to its initial value. + +\asubsection{Printing the current parameterization} + +The commands {\tt Print Natural Implicit}, {\tt Print Natural +Contractible} and {\tt Print \\ Natural Transparent} print the list of +constructions declared {\tt Implicit}, {\tt Contractible}, +{\tt Transparent} respectively. + +\asubsection{Interferences with \texttt{Reset}} + +The customization of \texttt{Natural} is dependent of the \texttt{Reset} +command. If you reset the environment back to a point preceding an +\verb=Add Natural ...= command, the effect of the command will be +erased. Similarly, a reset back to a point before a +\verb=Remove Natural ... = command invalidates the removal. + +\asection{Error messages} + +An error occurs when trying to \verb=Print=, to \verb=Add=, to +\verb=Test=, or to \verb=remove= an undefined ident. Similarly, an +error occurs when trying to set a language unknown from \Natural. +Errors may also occur when trying to parameterize the printing of +proofs: some parameterization are effectively forbidden. +Note that to \verb=Remove= an ident absent from a table or to +\verb=Add= to a table an already present ident does not lead to an +error. + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/Omega.tex b/doc/Omega.tex new file mode 100755 index 000000000..286c151c4 --- /dev/null +++ b/doc/Omega.tex @@ -0,0 +1,223 @@ +\achapter{\texttt{Omega}: a solver of quantifier-free problems in +Presburger Arithmetic} +\aauthor{Pierre Crégut} + +\asection{Description of {\tt Omega}} +\tacindex{Omega} +\label{description} + +{\tt Omega}~solves a goal in Presburger arithmetic, ie a universally +quantified formula made of equations and inequations. Equations may +be specified either on the type \verb=nat= of natural numbers or on +the type \verb=Z= of binary-encoded integer numbers. Formulas on +\verb=nat= are automatically injected into \verb=Z=. The procedure +may use any hypothesis of the current proof session to solve the goal. + +Multiplication is handled by {\tt Omega}~but only goals where at +least one of the two multiplicands of products is a constant are +solvable. This is the restriction meaned by ``Presburger arithmetic''. + +If the tactic cannot solve the goal, it fails with an error message. +In any case, the computation eventually stops. + +\asubsection{Arithmetical goals recognized by {\tt Omega}} + +{\tt Omega}~applied only to quantifier-free formulas built from the +connectors + +\begin{quote} +\verb=/\, \/, ~, ->= +\end{quote} + +on atomic formulas. Atomic formulas are built from the predicates + +\begin{quote} +\verb!=, le, lt, gt, ge! +\end{quote} + + on \verb=nat= or from the predicates + +\begin{quote} +\verb!=, <, <=, >, >=! +\end{quote} + + on \verb=Z=. In expressions of type \verb=nat=, {\tt Omega}~recognizes + +\begin{quote} +\verb!plus, minus, mult, pred, S, O! +\end{quote} + +and in expressions of type \verb=Z=, {\tt Omega}~recognizes + +\begin{quote} +\verb!+,_,*, Zs!, and constants. +\end{quote} + +All expressions of type \verb=nat= or \verb=Z= not built on these +operators are considered abstractly as if they +were arbitrary variables of type \verb=nat= or \verb=Z=. + +\asubsection{Messages from {\tt Omega}} +\label{errors} + +When {\tt Omega}~does not solve the goal, one of the following errors +is generated: + +\begin{ErrMsgs} +\item \errindex{Omega can't solve this system}\\ + This may happen if your goal is not quantifier-free (if it is + universally quantified, try {\tt Intros} first; if it contains + existentials quantifiers too, {\tt Omega}\ is not strong enough to solve your + goal). This may happen also if your goal contains arithmetical + operators unknown from {\tt Omega}. Finally, your goal may be really + wrong ! + +\item \errindex{Omega: Not a quantifier-free goal}\\ + If your goal is universally quantified, you should first apply {\tt + Intro} as many time as needed. + +\item \errindex{Omega: Unrecognized predicate or connective:{\rm\sl ident}} + +\item \errindex{Omega: Unrecognized atomic proposition:{\rm\sl prop}} + +\item \errindex{Omega: Can't solve a goal with proposition variables} + +\item \errindex{Omega: Unrecognized proposition} + +\item \errindex{Omega: Can't solve a goal with non-linear products} + +\item \errindex{Omega: Can't solve a goal with equality on {\rm\sl type}} + +\end{ErrMsgs} + +%% Ce code est débranché pour l'instant +%% +% \asubsection{Control over the output} +% There are some flags that can be set to get more information on the procedure + +% \begin{itemize} +% \item \verb=Time= to get the time used by the procedure +% \item \verb=System= to visualize the normalized systems. +% \item \verb=Action= to visualize the actions performed by the OMEGA +% procedure (see \ref{technical}). +% \end{itemize} + +% \comindex{Set Omega Time} +% \comindex{UnSet Omega Time} +% \comindex{Switch Omega Time} +% \comindex{Set Omega System} +% \comindex{UnSet Omega System} +% \comindex{Switch Omega System} +% \comindex{Set Omega Action} +% \comindex{UnSet Omega Action} +% \comindex{Switch Omega Action} + + Use {\tt Set Omega {\rm\sl flag}} to set the flag + {\rm\sl flag}. Use {\tt Unset Omega {\rm\sl flag}} to unset it and +{\tt Switch Omega {\rm\sl flag}} to toggle it. + +\section{Using {\tt Omega}} + +The tactic {\tt Omega}~does not belong to the core system. It should be +loaded by + +\begin{coq_example*} +Require Omega. +\end{coq_example*} + +\example{} + +\begin{coq_example} +Goal (m,n:Z) ~ `1+2*m = 2*n`. +Intros; Omega. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\example{} + +\begin{coq_example} +Goal (z:Z)`z>0` -> `2*z + 1 > z`. +Intro; Omega. +\end{coq_example} + +Other examples can be found in \verb+$COQLIB/theories/DEMOS/OMEGA+. + +\asection{Technical data} +\label{technical} + +\asubsection{Overview of the tactic} +\begin{itemize} + +\item The goal is negated twice and the first negation is introduced as an + hypothesis. +\item Hypothesis are decomposed in simple equations or inequations. Multiple + goals may result from this phase. +\item Equations and inequations over \verb=nat= are translated over + \verb=Z=, multiple goals may result from the translation of + substraction. +\item Equations and inequations are normalized. +\item Goals are solved by the {\it OMEGA} decision procedure. +\item The script of the solution is replayed. + +\end{itemize} + +\asubsection{Overview of the {\it OMEGA} decision procedure} + +The {\it OMEGA} decision procedure involved in the {\tt Omega}~tactic uses +a small subset of the decision procedure presented in + +\begin{quote} + "The Omega Test: a fast and practical integer programming +algorithm for dependence analysis", William Pugh, Communication of the +ACM , 1992, p 102-114. +\end{quote} + +Here is an overview. +The reader is refered to the original paper for more information. + +\begin{itemize} + +\item Equations and inequations are normalized by division by the GCD of their + coefficients. +\item Equations are eliminated, using the Banerjee test to get a coefficient + equal to one. +\item Note that each inequation defines a half space in the space of real value + of the variables. +\item Inequations are solved by projecting on the hyperspace defined by + cancelling one of the variable. + They are partitioned according to the sign of + the coefficient of the eliminated variable. Pairs of inequations from + different classes define a new edge in the projection. +\item Redundant inequations are eliminated or merged in new equations that can + be eliminated by the Banerjee test. +\item The last two steps are iterated until a contradiction is reached + (success) or there is no more variable to eliminate (failure). + +\end{itemize} + +It may happen that there is a real solution and no integer one. The last +steps of the Omega procedure (dark shadow) are not implemented, so the +decision procedure is only partial. + +\asection{Bugs} + +\begin{itemize} +\item The simplification procedure is very dumb and this results in + many redundant cases to explore. + +\item Much too slow. + +\item Certainely plenty other bugs !! You can report them to + +\begin{quote} + \verb=Pierre.Cregut@cnet.francetelecom.fr= +\end{quote} + +\end{itemize} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/Polynom.tex b/doc/Polynom.tex new file mode 100644 index 000000000..858b2d67a --- /dev/null +++ b/doc/Polynom.tex @@ -0,0 +1,500 @@ +\achapter{The \texttt{Ring} tactic} +\aauthor{Patrick Loiseleur and Samuel Boutin} +\label{Ring} +\tacindex{Ring} + +This chapter presents the \texttt{Ring} tactic. + +\asection{What does this tactic?} + +\texttt{Ring} does associative-commutative rewriting in ring and semi-ring +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 \textit{polynomial} is an expression built on variables $V_0, V_1, +\dots$ and constants by application of $\oplus$ and $\otimes$. + +Let an {\it ordered product} be a product of variables $V_{i_1} \otimes +\ldots \otimes V_{i_n}$ verifying $i_1 \le i_2 \le \dots \le i_n$. Let a +\textit{monomial} be the product of a constant (possibly equal to 1, in +which case we omit it) and an ordered product. We can order the +monomials by the lexicographic order on products of variables. Let a +\textit{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 \textit{normal form} of the polynomial. So what does \texttt{Ring}? It +normalizes polynomials over any ring or semi-ring structure. The basic +utility of \texttt{Ring} is to simplify ring expressions, so that the user +does not have to deal manually with the theorems of associativity and +commutativity. + +\begin{Examples} +\item In the ring of integers, the normal form of +$x (3 + yx + 25(1 - z)) + zx$ is $28x + (-24)xz + xxy$. +\item For the classical propositional calculus (or the boolean rings) + the normal form is what logicians call \textit{disjunctive normal + form}: every formula is equivalent to a disjunction of + conjunctions of atoms. (Here $\oplus$ is $\vee$, $\otimes$ is + $\wedge$, variables are atoms and the only constants are T and F) +\end{Examples} + +\asection{The variables map} + +It is frequent to have an expression built with + and + $\times$, but rarely on variables only. +Let us associate a number to each subterm of a ring +expression in the \gallina\ language. For example in the ring +\texttt{nat}, consider the expression: + +\begin{quotation} +\begin{verbatim} +(plus (mult (plus (f (5)) x) x) + (mult (if b then (4) else (f (3))) (2))) +\end{verbatim} +\end{quotation} + +\noindent As a ring expression, is has 3 subterms. Give each subterm a +number in an arbitrary order: + +\begin{tabular}{ccl} +0 & $\mapsto$ & \verb|if b then (4) else (f (3))| \\ +1 & $\mapsto$ & \verb|(f (5))| \\ +2 & $\mapsto$ & \verb|x| \\ +\end{tabular} + +\noindent Then normalize the ``abstract'' polynomial + +$$((V_1 \otimes V_2) \oplus V_2) \oplus (V_0 \otimes 2) $$ + +\noindent In our example the normal form is: + +$$(2 \otimes V_0) \oplus (V_1 \otimes V_2) \oplus (V_2 \otimes V_2)$$ + +\noindent Then substitute the variables by their values in the variables map to +get the concrete normal polynomial: + +\begin{quotation} +\begin{verbatim} +(plus (mult (2) (if b then (4) else (f (3)))) + (plus (mult (f (5)) x) (mult x x))) +\end{verbatim} +\end{quotation} + +\asection{Is it automatic?} + +Yes, building the variables map and doing the substitution after +normalizing is automatically done by the tactic. So you can just forget +this paragraph and use the tactic according to your intuition. + +\asection{Concrete usage in \Coq} + +Under a session launched by \texttt{coqtop} or \texttt{coqtop -full}, +load the \texttt{Ring} files with the command: + +\begin{quotation} +\begin{verbatim} +Require Ring. +\end{verbatim} +\end{quotation} + +It does not work under \texttt{coqtop -opt} because the compiled ML +objects used by the tactic are not linked in this binary image, and +dynamic loading of native code is not possible in \ocaml. + +In order to use \texttt{Ring} on naturals, load \texttt{ArithRing} +instead; for binary integers, load the module \texttt{ZArithRing}. + +Then, to normalize the terms $term_1$, \dots, $term_n$ in +the current subgoal, use the tactic: + +\begin{quotation} +\texttt{Ring} $term_1$ \dots{} $term_n$ +\end{quotation} +\tacindex{Ring} + +Then the tactic guesses the type of given terms, the ring theory to +use, the variables map, and replace each term with its normal form. +The variables map is common to all terms + +\Warning \texttt{Ring $term_1$; Ring $term_2$} is not equivalent to +\texttt{Ring $term_1$ $term_2$}. In the latter case the variables map +is shared between the two terms, and common subterm $t$ of $term_1$ +and $term_2$ will have the same associated variable number. + +\begin{ErrMsgs} +\item \errindex{All terms must have the same type} +\item \errindex{Don't know what to do with this goal} +\item \errindex{No Declared Ring Theory for \term.}\\ + \texttt{Use Add [Semi] Ring to declare it}\\ + That happens when all terms have the same type \term, but there is + no declared ring theory for this set. See below. +\end{ErrMsgs} + +\begin{Variants} +\item \texttt{Ring}\\ + That works if the current goal is an equality between two + polynomials. It will normalize both sides of the + equality, solve it if the normal forms are equal and in other cases + try to simplify the equality using \texttt{congr\_eqT} and \texttt{refl\_equal} + to reduce $x + y = x + z$ to $y = z$ and $x * z = x * y$ to $y = z$. + + \ErrMsg\errindex{This goal is not an equality} + +\end{Variants} + +\asection{Add a ring structure} + +It can be done in the \Coq toplevel (No ML file to edit and to link +with \Coq). First, \texttt{Ring} can handle two kinds of structure: +rings and semi-rings. Semi-rings are like rings without an opposite to +addition. Their precise specification (in \gallina) can be found in +the file + +\begin{quotation} +\begin{verbatim} +tactics/contrib/polynom/Ring_theory.v +\end{verbatim} +\end{quotation} + +The typical example of ring is \texttt{Z}, the typical +example of semi-ring is \texttt{nat}. + +The specification of a +ring is divided in two parts: first the record of constants +($\oplus$, $\otimes$, 1, 0, $\ominus$) and then the theorems +(associativity, commutativity, etc.). + +\begin{small} +\begin{flushleft} +\begin{verbatim} +Section Theory_of_semi_rings. + +Variable A : Type. +Variable Aplus : A -> A -> A. +Variable Amult : A -> A -> A. +Variable Aone : A. +Variable Azero : A. +(* There is also a "weakly decidable" equality on A. That means + that if (A_eq x y)=true then x=y but x=y can arise when + (A_eq x y)=false. On an abstract ring the function [x,y:A]false + is a good choice. The proof of A_eq_prop is in this case easy. *) +Variable Aeq : A -> A -> bool. + +Record Semi_Ring_Theory : Prop := +{ SR_plus_sym : (n,m:A)[| n + m == m + n |]; + SR_plus_assoc : (n,m,p:A)[| n + (m + p) == (n + m) + p |]; + + SR_mult_sym : (n,m:A)[| n*m == m*n |]; + SR_mult_assoc : (n,m,p:A)[| n*(m*p) == (n*m)*p |]; + SR_plus_zero_left :(n:A)[| 0 + n == n|]; + SR_mult_one_left : (n:A)[| 1*n == n |]; + SR_mult_zero_left : (n:A)[| 0*n == 0 |]; + SR_distr_left : (n,m,p:A) [| (n + m)*p == n*p + m*p |]; + SR_plus_reg_left : (n,m,p:A)[| n + m == n + p |] -> m==p; + SR_eq_prop : (x,y:A) (Is_true (Aeq x y)) -> x==y +}. +\end{verbatim} +\end{flushleft} +\end{small} + +\begin{small} +\begin{flushleft} +\begin{verbatim} +Section Theory_of_rings. + +Variable A : Type. + +Variable Aplus : A -> A -> A. +Variable Amult : A -> A -> A. +Variable Aone : A. +Variable Azero : A. +Variable Aopp : A -> A. +Variable Aeq : A -> A -> bool. + + +Record Ring_Theory : Prop := +{ Th_plus_sym : (n,m:A)[| n + m == m + n |]; + Th_plus_assoc : (n,m,p:A)[| n + (m + p) == (n + m) + p |]; + Th_mult_sym : (n,m:A)[| n*m == m*n |]; + Th_mult_assoc : (n,m,p:A)[| n*(m*p) == (n*m)*p |]; + Th_plus_zero_left :(n:A)[| 0 + n == n|]; + Th_mult_one_left : (n:A)[| 1*n == n |]; + Th_opp_def : (n:A) [| n + (-n) == 0 |]; + Th_distr_left : (n,m,p:A) [| (n + m)*p == n*p + m*p |]; + Th_eq_prop : (x,y:A) (Is_true (Aeq x y)) -> x==y +}. +\end{verbatim} +\end{flushleft} +\end{small} + +To define a ring structure on A, you must provide an addition, a +multiplication, an opposite function and two unities 0 and 1. + +You must then prove all theorems that make +(A,Aplus,Amult,Aone,Azero,Aeq) +a ring structure, and pack them with the \verb|Build_Ring_Theory| +constructor. + +Finally to register a ring the syntax is: + +\comindex{Add Ring} +\begin{quotation} + \texttt{Add Ring} \textit{A Aplus Amult Aone Azero Ainv Aeq T} + \texttt{[} \textit{c1 \dots cn} \texttt{].} +\end{quotation} + +\noindent where \textit{A} is a term of type \texttt{Set}, +\textit{Aplus} is a term of type \texttt{A->A->A}, +\textit{Amult} is a term of type \texttt{A->A->A}, +\textit{Aone} is a term of type \texttt{A}, +\textit{Azero} is a term of type \texttt{A}, +\textit{Ainv} is a term of type \texttt{A->A}, +\textit{Aeq} is a term of type \texttt{A->bool}, +\textit{T} is a term of type +\texttt{(Ring\_Theory }\textit{A Aplus Amult Aone Azero Ainv + Aeq}\texttt{)}. +The arguments \textit{c1 \dots cn}, +are the names of constructors which define closed terms: a +subterm will be considered as a constant if it is either one of the +terms \textit{c1 \dots cn} or the application of one of these terms to +closed terms. For \texttt{nat}, the given constructors are \texttt{S} +and \texttt{O}, and the closed terms are \texttt{O}, \texttt{(S O)}, +\texttt{(S (S O))}, \ldots + +\begin{Variants} +\item \texttt{Add Semi Ring} \textit{A Aplus Amult Aone Azero Aeq T} + \texttt{[} \textit{c1 \dots\ cn} \texttt{].}\comindex{Add Semi + Ring}\\ + There are two differences with the \texttt{Add Ring} command: + there is no inverse function and the term $T$ must be of type + \texttt{(Semi\_Ring\_Theory }\textit{A Aplus Amult Aone Azero + Aeq}\texttt{)}. + +\item \texttt{Add Abstract Ring} \textit{A Aplus Amult Aone Azero Ainv + Aeq T}\texttt{.}\comindex{Add Abstract Ring}\\ + This command should be used for when the operations of rings are not + computable; for example the real numbers of + \texttt{theories/REALS/}. Here $0+1$ is not beta-reduced to $1$ but + you still may want to \textit{rewrite} it to $1$ using the ring + axioms. The argument \texttt{Aeq} is not used; a good choice for + that function is \verb+[x:A]false+. + +\item \texttt{Add Abstract Semi Ring} \textit{A Aplus Amult Aone Azero + Aeq T}\texttt{.}\comindex{Add Abstract Semi Ring}\\ + +\end{Variants} + +\begin{ErrMsgs} +\item \errindex{Not a valid (semi)ring theory}.\\ + That happens when the typing condition does not hold. +\end{ErrMsgs} + +Currently, the hypothesis is made than no more than one ring structure +may be declared for a given type in \texttt{Set} or \texttt{Type}. +This allows automatic detection of the theory used to achieve the +normalization. On popular demand, we can change that and allow several +ring structures on the same set. + +The table of theories of \texttt{Ring} is compatible with the \Coq\ +sectioning mechanism. If you declare a Ring inside a section, the +declaration will be thrown away when closing the section. +And when you load a compiled file, all the \texttt{Add Ring} +commands of this file that are not inside a section will be loaded. + +The typical example of ring is \texttt{Z}, and the typical example of +semi-ring is \texttt{nat}. Another ring structure is defined on the +booleans. + +\Warning Only the ring of booleans is loaded by default with the +\texttt{Ring} module. To load the ring structure for \texttt{nat}, +load the module \texttt{ArithRing}, and for \texttt{Z}, +load the module \texttt{ZArithRing}. + + +\asection{How does it work?} + +The code of \texttt{Ring} a good example of tactic written using +\textit{reflection} (or \textit{internalization}, it is +synonymous). What is reflection? Basically, it is writing \Coq\ tactics +in \Coq, rather than in \ocaml. From the philosophical point of view, +it is using the ability of the Calculus of Constructions to speak and +reason about itself. +For the \texttt{Ring} tactic we used +\Coq\ as a programming language and also as a proof environment to build a +tactic and to prove it correctness. + +The interested reader is strongly advised to have a look at the file +\texttt{Ring\_normalize.v}. Here a type for polynomials is defined: + +\begin{small} +\begin{flushleft} +\begin{verbatim} +Inductive Type polynomial := + Pvar : idx -> polynomial +| Pconst : A -> polynomial +| Pplus : polynomial -> polynomial -> polynomial +| Pmult : polynomial -> polynomial -> polynomial +| Popp : polynomial -> polynomial. +\end{verbatim} +\end{flushleft} +\end{small} + +There is also a type to represent variables maps, and an +interpretation function, that maps a variables map and a polynomial to an +element of the concrete ring: + +\begin{small} +\begin{flushleft} +\begin{verbatim} +Definition polynomial_simplify := [...] +Definition interp : (varmap A) -> (polynomial A) -> A := [...] +\end{verbatim} +\end{flushleft} +\end{small} + +A function to normalize polynomials is defined, and the big theorem is +its correctness w.r.t interpretation, that is: + +\begin{small} +\begin{flushleft} +\begin{verbatim} +Theorem polynomial_simplify_correct : (v:(varmap A))(p:polynomial) + (interp v (polynomial_simplify p)) + ==(interp v p). +\end{verbatim} +\end{flushleft} +\end{small} + +(The actual code is slightly more complex: for efficiency, +there is a special datatype to represent normalized polynomials, +i.e. ``canonical sums''. But the idea is still the same). + +So now, what is the scheme for a normalization proof? Let \texttt{p} +be the polynomial expression that the user wants to normalize. First a +little piece of ML code guesses the type of \texttt{p}, the ring +theory \texttt{T} to use, an abstract polynomial \texttt{ap} and a +variables map \texttt{v} such that \texttt{p} is +$\beta\delta\iota$-equivalent to \verb|(interp v ap)|. Then we +replace it by \verb|(interp v (polynomial_simplify ap))|, using the +main correctness theorem and we reduce it to a concrete expression +\texttt{p'}, which is the concrete normal form of +\texttt{p}. This is summarized in this diagram: + +\medskip +\begin{tabular}{rcl} +\texttt{p} & $\rightarrow_{\beta\delta\iota}$ + & \texttt{(interp v ap)} \\ + & & $=_{\mathrm{(by\ the\ main\ correctness\ theorem)}}$ \\ +\texttt{p'} + & $\leftarrow_{\beta\delta\iota}$ + & \texttt{(interp v (polynomial\_simplify ap))} +\end{tabular} +\medskip + +The user do not see the right part of the diagram. +From outside, the tactic behaves like a +$\beta\delta\iota$ simplification extended with AC rewriting rules. +Basically, the proof is only the application of the main +correctness theorem to well-chosen arguments. + +\asection{History of \texttt{Ring}} + +First Samuel Boutin designed the tactic \texttt{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{coq_eval} +Require ZArith. +\end{coq_eval} +\begin{coq_example} +Goal (x,y,z:Z)`x + 3 + y + y*z = x + 3 + y + z*y`. +\end{coq_example} +\begin{coq_example*} +Intros; Rewrite (Zmult_sym y z); Reflexivity. +Save toto. +\end{coq_example*} +\begin{coq_example} +Print toto. +\end{coq_example} + +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 \texttt{ACDSimpl} was too slow, Samuel Boutin rewrote it +using reflection (see his article in TACS'97 \cite{Bou97}). Later, the +stuff was rewritten by Patrick +Loiseleur: the new tactic does not any more require \texttt{ACDSimpl} +to compile and it makes use of $\beta\delta\iota$-reduction +not only to replace the rewriting steps, but also to achieve the +interleaving of computation and +reasoning (see \ref{DiscussReflection}). He also wrote a +few ML code for the \texttt{Add Ring} command, that allow to register +new rings dynamically. + +Proofs terms generated by \texttt{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. + +\asection{Discussion} +\label{DiscussReflection} + +Efficiency is not the only motivation to use reflection +here. \texttt{Ring} also deals with constants, it rewrites for example the +expression $34 + 2*x -x + 12$ to the expected result $x + 46$. For the +tactic \texttt{ACDSimpl}, the only constants were 0 and 1. So the +expression $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 \mt 34; V_1 \mt 2; V_2 \mt x; V_3 \mt 12 \}$. Then it is +rewritten to $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 \textit{computation}) to achieve the +normalization. + +The tactic \texttt{Ring} is not only faster than a classical one: +using reflection, we get for free integration of computation and +reasoning that would be very complex to implement in the classic fashion. + +Is it the ultimate way to write tactics? +The answer is: yes and no. The \texttt{Ring} tactic +uses intensively the conversion +rule of \CIC, that is replaces proof by computation the most as it is +possible. It can be useful in all situations where a classical tactic +generates huge proof terms. Symbolic Processing and Tautologies are +in that case. But there are also tactics like \texttt{Auto} or +\texttt{Linear}: that do many complex computations, using side-effects +and backtracking, and generate + a small proof term. Clearly, it would be a non-sense to +replace them by tactics using reflection. + +Another argument against the reflection is that \Coq, as a +programming language, has many nice features, like dependent types, +but is very far from the +speed and the expressive power of \ocaml. Wait a minute! With \Coq\ +it is possible to extract ML code from \CIC\ terms, right? So, why not +to link the extracted code with \Coq\ to inherit the benefits of the +reflection and the speed of ML tactics? That is called \textit{total + reflection}, and is still an active research subject. With these +technologies it will become possible to bootstrap the type-checker of +\CIC, but there is still some work to achieve that goal. + +Another brilliant idea from Benjamin Werner: reflection could be used +to couple a external tool (a rewriting program or a model checker) +with \Coq. We define (in \Coq) a type of terms, a type of +\emph{traces}, and prove a correction theorem that states that +\emph{replaying traces} is safe w.r.t some interpretation. Then we let +the external tool do every computation (using side-effects, +backtracking, exception, or others features that are not available in +pure lambda calculus) to produce the trace: now we replay the trace in +Coq{}, and apply the correction lemma. So internalization seems to be +the best way to import \dots{} external proofs! + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/Program.tex b/doc/Program.tex new file mode 100644 index 000000000..9fd6080b8 --- /dev/null +++ b/doc/Program.tex @@ -0,0 +1,850 @@ +\achapter{The Program Tactic} +\aauthor{Catherine Parent} +\label{Addoc-program} + +The facilities described in this document pertain to a special aspect of +the \Coq\ system: how to associate to a functional program, whose +specification is written in \gallina, a proof of its correctness. + +This methodology is based on the Curry-Howard isomorphism between +functional programs and constructive proofs. This isomorphism allows +the synthesis of a functional program from the constructive part of its +proof of correctness. That is, it is possible to analyze a \Coq\ proof, +to erase all its non-informative parts (roughly speaking, removing the +parts pertaining to sort \Prop, considered as comments, to keep only the +parts pertaining to sort \Set). + +This {\sl realizability interpretation} +was defined by Christine Paulin-Mohring in her PhD dissertation +\cite{Moh89b}, and +implemented as a {\sl program extraction} facility in previous versions of +\Coq~ by Benjamin Werner (see \cite{COQ93}). +However, the corresponding certified program +development methodology was very awkward: the user had to understand very +precisely the extraction mechanism in order to guide the proof construction +towards the desired algorithm. The facilities described in this chapter +attempt to do the reverse: i.e. to try and generate the proof of correctness +from the program itself, given as argument to a specialized tactic. +This work is based on the PhD dissertation of +Catherine Parent (see \cite{CPar95}) + +\asection{Developing certified programs: Motivations} +\label{program_proving} + +We want to develop certified programs automatically proved by the +system. That is to say, instead of giving a specification, an +interactive proof and then extracting a program, the user gives the +program he wants to prove and the corresponding specification. Using +this information, an automatic proof is developed which solves the +``informative'' goals without the help of the user. When the proof is +finished, the extracted program is guaranteed to be correct and +corresponds to the one given by the user. The tactic uses the fact +that the extracted program is a skeleton of its corresponding proof. + +\asection{Using {\tt Program}} +The user has to give two things: the specification (given as usual by +a goal) and the program (see section \ref{program-syntax}). Then, this program +is associated to the current goal (to know which specification it +corresponds to) and the user can use different tactics to develop an +automatic proof. + +\asubsection{\tt Realizer \term.} +\tacindex{Realizer} +\label{Realizer} +This command attaches a program {\term} to the current goal. This is a +necessary step before applying the first time the tactic {\tt +Program}. The syntax of programs is given in section \ref{program-syntax}. +If a program is already attached to the current subgoal, {\tt +Realizer} can be also used to change it. + +\asubsection{\tt Show Program.} +\comindex{Show Program}\label{Show Program} +The command \verb=Show Program= shows the program associated to the +current goal. The variant \verb=Show Program n= shows the program associated to +the nth subgoal. + +\asubsection{\tt Program.} +\tacindex{Program}\label{Program} +This tactics tries to build a proof of the current subgoal from the +program associated to the current goal. This tactic performs +\verb=Intros= then either one \verb=Apply= or one \verb=Elim= +depending on the syntax of the program. The \verb=Program= tactic +generates a list of subgoals which can be either logical or +informative. Subprograms are automatically attached to the informative +subgoals. + +When attached program are not automatically generated, an initial program +has to be given by {\tt Realizer}. + +\begin{ErrMsgs} +\item \errindex{No program associated to this subgoal}\\ +You need to attach a program to the current goal by using {\tt Realizer}. +Perhaps, you already attached a program but a {\tt Restart} or an +{\tt Undo} has removed it. +\item \errindex{Type of program and informative extraction of goal do not coincide} +\item \errindex{Cannot attach a realizer to a logical goal}\\ +The current goal is non informative (it lives in the world {\tt Prop} +of propositions or {\tt Type} of abstract sets) while it should lives +in the world {\tt Set} of computational objects. +\item \errindex{Perhaps a term of the Realizer is not an FW + term}\texttt{ and you then have to replace it by its extraction}\\ +Your program contains non informative subterms. +\end{ErrMsgs} + +\begin{Variants} +\item{\tt Program\_all.} + \tacindex{Program\_all}\label{Program_all}\\ + This tactic is equivalent to the composed tactic + \verb=Repeat (Program OrElse Auto)=. It repeats the \verb=Program= + tactic on every informative subgoal and tries the \verb=Auto= tactic + on the logical subgoals. Note that the work of the \verb=Program= + tactic is considered to be finished when all the informative subgoals + have been solved. This implies that logical lemmas can stay at the end + of the automatic proof which have to be solved by the user. +\item {\tt Program\_Expand} + \tacindex{Program\_Expand}\label{Program_Expand}\\ + The \verb=Program_Expand= tactic transforms the current program into + the same program with the head constant expanded. This tactic + particularly allows the user to force a program to be reduced before + each application of the \verb=Program= tactic. + + \begin{ErrMsgs} + \item \errindex{Not reducible}\\ + The head of the program is not a constant or is an opaque constant. + need to attach a program to the current goal by using {\tt Realizer}. + Perhaps, you already attached a program but a {\tt Restart} or an + {\tt Undo} has removed it. + \end{ErrMsgs} +\end{Variants} + +\asubsection{Hints for {\tt Program}} + +\begin{description} +\item[Mutual inductive types] The \verb=Program= tactic can deal with + mutual inductive types. But, this needs the use of + annotations. Indeed, when associating a mutual fixpoint program to a + specification, the specification is associated to the first (the + outermost) function defined by the fixpoint. But, the specifications + to be associated to the other functions cannot be automatically + derived. They have to be explicitly given by the user as + annotations. See section \ref{program-ex-mutual} for an example. + +\item[Constants] The \verb=Program= tactic is very sensitive to the + status of constants. Constants can be either opaque (their body + cannot be viewed) or transparent. The best of way of doing is to + leave constants opaque (this is the default). If it is needed after, + it is best to use the \verb=Transparent= command {\bf after} having + used the \verb=Program= tactic. +\end{description} + +\asection{Syntax for programs} +\label{program-syntax} +\asubsection{Pure programs} +The language to express programs is called \real\footnote{It + corresponds to \FW\ plus inductive definitions}. Programs are +explicitly typed\footnote{This information is not strictly needed but + was useful for type checking in a first experiment.} like terms +extracted from proofs. Some extra expressions have been added to have +a simpler syntax. + +This is the raw form of what we call pure programs. But, in fact, it +appeared that this simple type of programs is not sufficient. Indeed, +all the logical part useful for the proof is not contained in these +programs. That is why annotated programs are introduced. + +\asubsection{Annotated programs} +The notion of annotation introduces in a program a logical assertion +that will be used for the proof. The aim of the \verb=Program= tactic +is to start from a specification and a program and to generate +subgoals either logical or associated with programs. However, to find +the good specification for subprograms is not at all trivial in +general. For instance, if we have to find an invariant for a loop, or +a well founded order in a recursive call. + +So, annotations add in a program the logical part which is needed for +the proof and which cannot be automatically retrieved. This allows the +system to do proofs it could not do otherwise. + +For this, a particular syntax is needed which is the following: since +they are specifications, annotations follow the same internal syntax +as \Coq~terms. We indicate they are annotations by putting them +between \verb={= and \verb=}= and preceding them with \verb=:: ::=. +Since annotations are \Coq~terms, they can involve abstractions over +logical propositions that have to be declared. Annotated-$\lambda$ +have to be written between \verb=[{= and \verb=}]=. +Annotated-$\lambda$ can be seen like usual $\lambda$-bindings but +concerning just annotations and not \Coq~programs. + +\asubsection{Recursive Programs} +Programs can be recursively defined using the following syntax: \verb=<={\it + type-of-the-result}\verb=> rec= \index{rec@{\tt rec}} {\it + name-of-the-induction-hypothesis} \verb=:: :: {= {\it + well-founded-order-of-the-recursion} \verb=}= and then the body of +the program (see section \ref{program-examples}) which must always begin with +an abstraction [x:A] where A is the type of the arguments of the +function (also on which the ordering relation acts). + +\asubsection{Implicit arguments} + +A synthesis of implicit arguments has been added in order to +allow the user to write a minimum of types in a program. Then, it is +possible not to write a type inside a program term. This type has then +to be automatically synthesized. For this, it is necessary to indicate +where the implicit type to be synthesized appears. The syntax is the +current one of implicit arguments in \Coq: the question mark +\verb+?+. + +This synthesis of implicit arguments is not possible everywhere in a +program. In fact, the synthesis is only available inside a +\verb+Match+, a \verb+Cases+ or a \verb+Fix+ construction (where +\verb+Fix+ is a syntax for defining fixpoints). + +\asubsection{Grammar} +The grammar for programs is described in figure \ref{pgm-syntax}. + +\begin{figure} +\begin{tabular}{lcl} +{\pg} & ::= & {\ident}\\ + & $|$ & {\tt ?} \\ + & $|$ & {\tt [} {\ident} {\tt :} {\pg} {\tt ]} {\pg} \\ + & $|$ & {\tt [} {\ident} {\tt ]} {\pg} \\ + & $|$ & {\tt (} {\ident} {\tt :} {\pg} {\tt )} {\pg} \\ + & $|$ & {\tt (} {\pgs} {\tt )} \\ + & $|$ & {\tt Match} {\pg} {\tt with} {\pgs} {\tt end} \\ + & $|$ & \verb=<={\pg}\verb=>={\tt Match} {\pg} {\tt with} {\pgs} {\tt end} \\ + & $|$ & {\tt Cases} {\pg} {\tt of} \sequence{\eqn} {|} {\tt end} \\ + & $|$ & \verb=<={\pg}\verb=>={\tt Cases} {\pg} {\tt of} + \sequence{\eqn} {|} {\tt end} \\ + & $|$ & {\tt Fix} {\ident} \verb.{.\nelist{\fixpg}{with} \verb.}. \\ + & $|$ & {\tt Cofix} {\ident} \{{\ident} {\tt :} {\pg} {\tt :=} {\pg} + {\tt with} {\ldots} {\tt with} {\ident} {\tt :} {\pg} {\tt :=} {\pg}\} \\ + & $|$ & {\pg} {\tt ::} {\tt ::} \{ {\term} \} \\ + & $|$ & {\tt [\{} {\ident} {\tt :} {\term} {\tt \}]} {\pg} \\ + & $|$ & {\tt let} + {\tt (} {\ident} {\tt ,} {\ldots} {\tt ,} {\ident} {\tt ,} {\dots} + {\tt ,} {\ident} {\tt )} {\tt =} {\pg} {\tt in} {\pg} \\ +% & $|$ & \verb=<={\pg}\verb=>={\tt let} {\tt (} {\ident} {\tt ,} {\ldots} {\tt +% ,} {\ident} {\tt :} {\pg} {\tt ;} {\ldots} {\tt ;} {\ident} {\tt ,} +% {\ldots} {\tt ,} {\ident} {\tt :} {\pg} {\tt )} {\tt =} {\pg} {\tt +% in} {\pg} \\ + & $|$ & \verb=<={\pg}\verb=>={\tt let} {\tt (} {\ident} {\tt ,} + {\ldots} {\tt ,} {\ldots} {\tt ,} {\ident} {\tt )} {\tt =} {\pg} {\tt + in} {\pg} \\ + & $|$ & {\tt if} {\pg} {\tt then} {\pg} {\tt else} {\pg} \\ + & $|$ & \verb=<={\pg}\verb=>={\tt if} {\pg} {\tt then} {\pg} {\tt + else} {\pg} \\ + & $|$ & \verb=<={\pg}\verb=>={\tt rec} {\ident} {\tt ::} {\tt ::} \{ \term \} + {\tt [} {\ident} {\tt :} {\pg} {\tt ]} {\pg} \\ + {\pgs} & ::= & \pg \\ + & $|$ & {\pg} {\pgs}\\ +{\fixpg} & ::= & {\ident} {\tt [} \nelist{\typedidents}{;} {\tt ]} {\tt :} {\pg} {\tt :=} {\pg} \\ + & $|$ & {\ident} {\tt /} {\num} {\tt :} {\pg} {\tt :=} {\pg} {\tt ::} {\tt ::} \{ {\term} \} \\ +{\simplepattern} & ::= & {\ident} \\ + & $|$ & \verb!(! \nelist{\ident}{} \verb!)! \\ +{\eqn} & ::= & {\simplepattern} ~\verb!=>! ~\pg \\ +\end{tabular} +\caption{Syntax of annotated programs} +\label{pgm-syntax} +\end{figure} + +As for {\Coq} terms (see section \ref{term}), {\tt (}{\pgs}{\tt )} +associates to the left. The syntax of {\term} is the one in section. +The infix annotation operator \verb!:: ::! binds more than the +abstraction and product constructions. +\ref{term}. + +The reference to an identifier of the \Coq\ context (in particular a +constant) inside a program of the +language \real\ is a reference to its extracted contents. + +\asection{Examples} +\label{program-examples} +\asubsection{Ackermann Function} +Let us give the specification of Ackermann's function. We want to +prove that for every $n$ and $m$, there exists a $p$ such that +$ack(n,m)=p$ with: + +\begin{eqnarray*} +ack(0,n) & = & n+1 \\ +ack(n+1,0) & = & ack(n,1) \\ +ack(n+1,m+1) & = & ack(n,ack(n+1,m)) +\end{eqnarray*} + +An ML program following this specification can be: + +\begin{verbatim} +let rec ack = function + 0 -> (function m -> Sm) + | Sn -> (function 0 -> ack n 1 + | Sm -> ack n (ack Sn m)) +\end{verbatim} + +Suppose we give the following definition in \Coq~of a ternary relation +\verb=(Ack n m p)= in a Prolog like form representing $p=ack(n,m)$: + +\begin{coq_example*} +Inductive Ack : nat->nat->nat->Prop := + AckO : (n:nat)(Ack O n (S n)) + | AcknO : (n,p:nat)(Ack n (S O) p)->(Ack (S n) O p) + | AckSS : (n,m,p,q:nat)(Ack (S n) m q)->(Ack n q p) + ->(Ack (S n) (S m) p). +\end{coq_example*} +Then the goal is to prove that $\forall n,m .\exists p.(Ack~n~m~p)$, so +the specification is: + +\verb!(n,m:nat){p:nat|(Ack n m p)}!. +The associated {\real} program corresponding to the above ML program can be defined as a fixpoint: +\begin{coq_example*} +Fixpoint ack_func [n:nat] : nat -> nat := + Cases n of + O => [m:nat](S m) + | (S n') => Fix ack_func2 {ack_func2 [m:nat] : nat := + Cases m of + O => (ack_func n' (S O)) + | (S m') => (ack_func n' (ack_func2 m')) + end} + end. +\end{coq_example*} +The program is associated by using \verb=Realizer ack_func=. The +program is automatically expanded. Each realizer which is a constant +is automatically expanded. Then, by repeating the \verb=Program= +tactic, three logical lemmas are generated and are easily solved by +using the property Ack0, Ackn0 and AckSS. +\begin{coq_eval} +Goal (n,m:nat){p:nat|(Ack n m p)}. +Realizer ack_func. +\end{coq_eval} +\begin{coq_example} +Repeat Program. +\end{coq_example} + + +\asubsection{Euclidean Division} +This example shows the use of {\bf recursive programs}. Let us +give the specification of the euclidean division algorithm. We want to +prove that for $a$ and $b$ ($b>0$), there exist $q$ and $r$ such that +$a=b*q+r$ and $b>r$. + +An ML program following this specification can be: +\begin{verbatim} +let div b a = divrec a where rec divrec = function + if (b<=a) then let (q,r) = divrec (a-b) in (Sq,r) + else (0,a) +\end{verbatim} +Suppose we give the following definition in \Coq~which describes what +has to be proved, ie, $\exists q \exists r.~(a=b*q+r \wedge ~b>r)$: +\begin{coq_eval} +Abort. +Require Arith. +\end{coq_eval} +\begin{coq_example*} +Inductive diveucl [a,b:nat] : Set + := divex : (q,r:nat)(a=(plus (mult q b) r))->(gt b r) + ->(diveucl a b). +\end{coq_example*} +The decidability of the ordering relation has to be proved first, by +giving the associated function of type \verb!nat->nat->bool!: +\begin{coq_example*} +Theorem le_gt_dec : (n,m:nat){(le n m)}+{(gt n m)}. +Realizer Fix le_gt_bool {le_gt_bool [n:nat] : nat -> bool := + Cases n of + | O => [m:nat]true + | (S n') => [m:nat]Cases m of + | O => false + | (S m') => (le_gt_bool n' m') + end + end}. +Program_all. +Save. +\end{coq_example*} +Then the specification is \verb!(b:nat)(gt b O)->(a:nat)(diveucl a b)!. +The associated program corresponding to the ML program will be: +\begin{coq_eval} +Definition lt := [n,m:nat](gt m n). +Theorem eucl_dev : (b:nat)(gt b O)->(a:nat)(diveucl a b). +\end{coq_eval} +\begin{coq_example*} +Realizer + [b:nat](<nat*nat>rec div :: :: { lt } + [a:nat]if (le_gt_dec b a) + then let (q,r) = (div (minus a b)) + in ((S q),r) + else (O,a)). +\end{coq_example*} +Where \verb=lt= is the well-founded ordering relation defined by: +\begin{coq_example} +Print lt. +\end{coq_example} +Note the syntax for recursive programs as explained before. The +\verb=rec= construction needs 4 arguments: the type result of the +function (\verb=nat*nat= because it returns two natural numbers) +between \verb=<= and \verb=>=, the name of the induction hypothesis +(which can be used for recursive calls), the ordering relation +\verb=lt= (as an annotation because it is a specification), and the +program itself which must begin with a $\lambda$-abstraction. The +specification of \verb=le_gt_dec= is known because it is a previous +lemma. +The term \verb!(le_gt_dec b a)! is seen by the \verb!Program! tactic +as a term of type \verb!bool! which satisfies the specification +\verb!{(le a b)}+{(gt a b)}!. +The tactics \verb=Program_all= or \verb=Program= can be used, and the +following logical lemmas are obtained: +\begin{coq_example} +Repeat Program. +\end{coq_example} +The subgoals 4, 5 and 6 are resolved by \verb=Auto= (if you use +\verb=Program_all= they don't appear, because \verb=Program_all= tries +to apply \verb=Auto=). The other ones have to be solved by the user. + + +\asubsection{Insertion sort} +This example shows the use of {\bf annotations}. Let us give the +specification of a sorting algorithm. We want to prove that for a +sorted list of natural numbers $l$ and a natural number $a$, we can +build another sorted list $l'$, containing all the elements of $l$ +plus $a$. + +An ML program implementing the insertion sort and following this +specification can be: +\begin{verbatim} +let sort a l = sortrec l where rec sortrec = function + [] -> [a] + | b::l' -> if a<b then a::b::l' else b::(sortrec l') +\end{verbatim} +Suppose we give the following definitions in \Coq: + +First, the decidability of the ordering relation: +\begin{coq_eval} +Restore State Initial. +Require Le. +Require Gt. +\end{coq_eval} +\begin{coq_example*} +Fixpoint inf_dec [n:nat] : nat -> bool := +[m:nat]Cases n of + O => true + | (S n') => Cases m of + O => false + | (S m') => (inf_dec n' m') + end + end. +\end{coq_example*} + +The definition of the type \verb=list=: +\begin{coq_example*} +Inductive list : Set := nil : list | cons : nat -> list -> list. +\end{coq_example*} + +We define the property for an element \verb=x= to be {\bf in} a list +\verb=l= as the smallest relation such that: $\forall a \forall +l~(In~x~l) \Ra (In~x~(a::l))$ and $\forall l~(In~x~(x::l))$. +\begin{coq_example*} +Inductive In [x:nat] : list->Prop + := Inl : (a:nat)(l:list)(In x l) -> (In x (cons a l)) + | Ineq : (l:list)(In x (cons x l)). +\end{coq_example*} + +A list \verb=t'= is equivalent to a list \verb=t= with one added +element \verb=y= iff: $(\forall x~(In~x~t) \Ra (In~x~t'))$ and +$(In~y~t')$ and $\forall x~(In~x~t') \Ra ((In~x~t) \vee y=x)$. The +following definition implements this ternary conjunction. +\begin{coq_example*} +Inductive equiv [y:nat;t,t':list]: Prop := + equiv_cons : + ((x:nat)(In x t)->(In x t')) + -> (In y t') + ->((x:nat)(In x t')->((In x t)\/y=x)) + -> (equiv y t t'). +\end{coq_example*} + +Definition of the property of list to be sorted, still defined +inductively: +\begin{coq_example*} +Inductive sorted : list->Prop + := sorted_nil : (sorted nil) + | sorted_trans : (a:nat)(sorted (cons a nil)) + | sorted_cons : (a,b:nat)(l:list)(sorted (cons b l)) -> (le a b) + -> (sorted (cons a (cons b l))). +\end{coq_example*} +Then the specification is:\\ +\verb!(a:nat)(l:list)(sorted l)->{l':list|(equiv a l l')&(sorted l')}!. + +The associated \real\ program corresponding to the ML program will be: +\begin{coq_eval} +Lemma toto : (a:nat)(l:list)(sorted l)->{l':list|(equiv a l l')&(sorted l')}. +\end{coq_eval} +\begin{coq_example*} +Realizer + Fix list_insert{list_insert [a:nat; l:list] : list := + Cases l of + | nil => (cons a nil) + | (cons b m) => + if (inf_dec b a) :: :: { {(le b a)}+{(gt b a)} } + then (cons b (list_insert a m)) + else (cons a (cons b m)) + end}. +\end{coq_example*} +% Realizer [a:nat][l:list] +% Match l with +% (cons a nil) +% [b,m,H]if (inf_dec b a) :: :: { {(le b a)}+{(gt b a)} } +% then (cons b H) +% else (cons a (cons b m)) +% end. +Note that we have defined \verb=inf_dec= as the program realizing the +decidability of the ordering relation on natural numbers. But, it has +no specification, so an annotation is needed to give this +specification. This specification is used and then the decidability of +the ordering relation on natural numbers has to be proved using the +index program. + +Suppose \verb=Program_all= is used, a few logical +lemmas are obtained (which have to be solved by the user): +\begin{coq_example} +Program_all. +\end{coq_example} + + +\asubsection{Quicksort} +This example shows the use of {\bf programs using previous +programs}. Let us give the specification of Quicksort. We want to +prove that for a list of natural numbers $l$, we can build a sorted +list $l'$, which is a permutation of the previous one. + +An ML program following this specification can be: +\begin{verbatim} +let rec quicksort l = function + [] -> [] + | a::m -> let (l1,l2) = splitting a m in + let m1 = quicksort l1 and + let m2 = quicksort l2 in m1@[a]@m2 +\end{verbatim} +Where \verb=splitting= is defined by: +\begin{verbatim} +let rec splitting a l = function + [] -> ([],[]) + | b::m -> let (l1,l2) = splitting a m in + if a<b then (l1,b::l2) + else (b::l1,l2) +\end{verbatim} +Suppose we give the following definitions in \Coq: + +Declaration of the ordering relation: +\begin{coq_eval} +Restore State Initial. +Require List. +Require Gt. +\end{coq_eval} +\begin{coq_example*} +Variable inf : A -> A -> Prop. +Definition sup := [x,y:A]~(inf x y). +Hypothesis inf_sup : (x,y:A){(inf x y)}+{(sup x y)}. +\end{coq_example*} +Definition of the concatenation of two lists: +\begin{coq_eval} +Save State toto. +\end{coq_eval} +\begin{coq_example*} +Fixpoint app [l:list] : list -> list + := [m:list]Cases l of + nil => m + | (cons a l1) => (cons a (app l1 m)) end. +\end{coq_example*} +\begin{coq_eval} +Restore State toto. +\end{coq_eval} +Definition of the permutation of two lists: +\begin{coq_eval} +Definition mil := [a:A][l,m:list](app l (cons a m)) : A->list->list->list. +Lemma mil_app : (a:A)(l,m,n:list)(mil a l (app m n))=(app (mil a l m) n). + Intros. + Unfold mil. + Elim (ass_app l (cons a m) n). + Auto. +Save. +\end{coq_eval} +\begin{coq_example*} +Inductive permut : list->list->Prop := + permut_nil : (permut nil nil) + |permut_tran : (l,m,n:list)(permut l m)->(permut m n)->(permut l n) + |permut_cmil : (a:A)(l,m,n:list) + (permut l (app m n))->(permut (cons a l) (mil a m n)) + |permut_milc : (a:A)(l,m,n:list) + (permut (app m n) l)->(permut (mil a m n) (cons a l)). +\end{coq_example*} +\begin{coq_eval} +Hints Resolve permut_nil permut_cmil permut_milc. +Lemma permut_cons : (a:A)(l,m:list)(permut l m)->(permut (cons a l) (cons a m)). + Intros. + Change (permut (cons a l) (mil a nil m)). + Auto. +Save. +Hints Resolve permut_cons. +Lemma permut_refl : (l:list)(permut l l). + Induction l ; Auto. +Save. +Hints Resolve permut_refl. +Lemma permut_sym : (l,m:list)(permut l m)->(permut m l). + Intros l m h1 ; Elim h1 ; Auto. + Intros l0 m0 n h2 h3 h4 h5. + Apply permut_tran with m0 ; Auto. +Save. +Hints Immediate permut_sym. +Lemma permut_app1 : (m1,n1,l:list)(permut m1 n1)->(permut (app l m1) (app l n1)). + Intros ; Elim l ; Simpl ; Auto. +Save. +Hints Resolve permut_app1. +Lemma permut_app_mil : (a:A)(l1,m1,l2,m2,n2:list) + (permut (app l1 m1) (app (app l2 m2) n2)) + -> (permut (app (cons a l1) m1) (app (mil a l2 m2) n2)). + Intros ; Simpl. + Elim (mil_app a l2 m2 n2). + Apply permut_cmil. + Elim (app_ass l2 m2 n2) ; Auto. +Save. +Hints Resolve permut_app_mil. +Lemma permut_app_app : (m1,m2,n1,n2 :list) + (permut m1 n1)->(permut m2 n2)->(permut (app m1 m2) (app n1 n2)). + Intros m1 m2 n1 n2 h1 h2. + Elim h1 ; Intros. + Exact h2. + Apply permut_tran with (app m n2) ; Auto. + Apply permut_tran with (app m m2) ; Auto. + Auto. + Apply permut_sym ; Auto. +Save. +Hints Resolve permut_app_app. +Lemma permut_app : (m,m1,m2,n1,n2 :list)(permut m1 n1)->(permut m2 n2)-> + (permut m (app m1 m2))->(permut m (app n1 n2)). + Intros. + Apply permut_tran with (app m1 m2) ; Auto. +Save. +\end{coq_eval} +The definitions \verb=inf_list= and \verb=sup_list= allow to know if +an element is lower or greater than all the elements of a list: +\begin{coq_example*} +Section Rlist_. +Variable R : A->Prop. +Inductive Rlist : list -> Prop := + Rnil : (Rlist nil) + | Rcons : (x:A)(l:list)(R x)->(Rlist l)->(Rlist (cons x l)). +\end{coq_example*} +\begin{coq_eval} +Hints Resolve Rnil Rcons. +Lemma Rlist_app : (m,n:list)(Rlist m)->(Rlist n)->(Rlist (app m n)). + Intros m n h1 h2 ; Elim h1 ; Simpl ; Auto. +Save. +Hints Resolve Rlist_app. +Section Rlist_cons_. +Variable a : A. +Variable l : list. +Hypothesis Rc : (Rlist (cons a l)). +Lemma Rlist_cons : (R a)/\(Rlist l). + Inversion_clear Rc; Auto. +Save. +End Rlist_cons_. +Section Rlist_append. +Variable n,m : list. +Lemma Rlist_appd : (Rlist (app n m))->((Rlist n)/\(Rlist m)). +Elim n ; Simpl; Auto. +Intros a y h1 h2. +Elim (Rlist_cons a (app y m)) ; Auto. +Intros h3 h4; Elim h1 ; Auto. +Save. +End Rlist_append. +Hints Resolve Rlist_appd. +Lemma Rpermut : (m,n:list)(permut m n)->(Rlist m)->(Rlist n). + Intros m n h1 ; Elim h1 ; Unfold mil ; Auto. + Intros a l m0 n0 h2 h3 h4. + Elim (Rlist_cons a l); Auto. + Intros h5 h6; Elim (Rlist_appd m0 n0); Auto. + Intros a l m0 n0 h2 h3 h4. + Elim (Rlist_appd m0 (cons a n0)) ; Auto. + Intros h5 h6; Elim (Rlist_cons a n0) ; Auto. +Save. +\end{coq_eval} +\begin{coq_example*} +End Rlist_. +Hints Resolve Rnil Rcons. +\end{coq_example*} +\begin{coq_eval} +Hints Resolve Rlist_app. +\end{coq_eval} +\begin{coq_example*} +Section Inf_Sup. +Hypothesis x : A. +Hypothesis l : list. +Definition inf_list := (Rlist (inf x) l). +Definition sup_list := (Rlist (sup x) l). +End Inf_Sup. +\end{coq_example*} +\begin{coq_eval} +Hints Unfold inf_list sup_list. +\end{coq_eval} +Definition of the property of a list to be sorted: +\begin{coq_example*} +Inductive sort : list->Prop := + sort_nil : (sort nil) + | sort_mil : (a:A)(l,m:list)(sup_list a l)->(inf_list a m) + ->(sort l)->(sort m)->(sort (mil a l m)). +\end{coq_example*} +\begin{coq_eval} +Hints Resolve sort_nil sort_mil. +Lemma permutapp : (a0:A)(y,l1,l2:list)(permut y (app l1 l2))->(permut (cons a0 y) (app l1 (cons a0 l2))). +Intros. +Exact (permut_cmil a0 y l1 l2 H). +Save. +Hints Resolve permutapp. +Lemma sortmil : (a:A)(x,x0,l1,l2:list)(sup_list a l1)->(inf_list a l2)->(sort x)->(sort x0)->(permut l1 x)->(permut l2 x0)->(sort (mil a x x0)). +Intros. +Apply sort_mil ; Auto. +Unfold sup_list ; Apply Rpermut with l1 ; Auto. +Unfold inf_list ; Apply Rpermut with l2 ; Auto. +Save. +\end{coq_eval} + +\noindent Then the goal to prove is +$\forall l~\exists m~(sort~m) \wedge (permut~l~m)$ and the specification is + +\verb!(l:list){m:list|(sort m)&(permut l m)!. + +\noindent Let us first prove a preliminary lemma. Let us define \verb=ltl= a +well-founded ordering relation. + +\begin{coq_example*} +Definition ltl := [l,m:list](gt (length m) (length l)). +\end{coq_example*} +\begin{coq_eval} +Hints Unfold ltl. +Lemma ltl_cons : (a,a0:A)(l1,y:list)(ltl l1 (cons a y))->(ltl l1 (cons a (cons a0 y))). +Unfold ltl; Simpl; Auto. +Save. +Hints Resolve ltl_cons. +Lemma ltl_cons_cons : (a,a0:A)(l2,y:list)(ltl l2 (cons a y))->(ltl (cons a0 l2) (cons a (cons a0 y))). +Unfold ltl; Simpl; Auto with arith.. +Save. +Hints Resolve ltl_cons_cons. +Require Wf_nat. +\end{coq_eval} +Let us then give a definition of \verb=Splitting_spec= corresponding +to\\ +$\exists l_1 \exists l_2.~(sup\_list~a~l_1) \wedge (inf\_list~a~l_2) +\wedge (l \equiv l_1@l_2) \wedge (ltl~l_1~(a::l)) \wedge +(ltl~l2~(a::l))$ and a theorem on this definition. +\begin{coq_example*} +Inductive Splitting_spec [a:A; l:list] : Set := + Split_intro : (l1,l2:list)(sup_list a l1)->(inf_list a l2) + ->(permut l (app l1 l2)) + ->(ltl l1 (cons a l))->(ltl l2 (cons a l)) + ->(Splitting_spec a l). +\end{coq_example*} +\begin{coq_example*} +Theorem Splitting : (a:A)(l:list)(Splitting_spec a l). +Realizer + Fix split {split [a:A;l:list] : list*list := + Cases l of + | nil => (nil,nil) + | (cons b m) => let (l1,l2) = (split a m) in + if (inf_sup a b) + then (* inf a b *) (l1,(cons b l2)) + else (* sup a b *) ((cons b l1),l2) + end}. +Program_all. +Simpl; Auto. +Save. +\end{coq_example*} +% Realizer [a:A][l:list] +% Match l with +% (* nil *) (nil,nil) +% (* cons *) [b,m,ll]let (l1,l2) = ll in +% if (inf_sup a b) +% then (* inf a b *) (l1,(cons b l2)) +% else (* sup a b *) ((cons b l1),l2) +% end. + +The associated {\real} program to the specification we wanted to first +prove and corresponding to the ML program will be: +\begin{coq_example*} +Lemma Quicksort: (l:list){m:list|(sort m)&(permut l m)}. +Realizer <list>rec quick :: :: { ltl } + [l:list]Cases l of + nil => nil + | (cons a m) => let (l1,l2) = (Splitting a m) in + (mil a (quick l1) (quick l2)) + end. +\end{coq_example*} +Then \verb=Program_all= gives the following logical lemmas (they have +to be resolved by the user): +\begin{coq_example} +Program_all. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\asubsection{Mutual Inductive Types} +\label{program-ex-mutual} +This example shows the use of {\bf mutual inductive types} with +\verb=Program=. Let us give the specification of trees and forest, and +two predicate to say if a natural number is the size of a tree or a +forest. + +\begin{coq_example*} +Section TreeForest. + +Variable A : Set. + +Mutual Inductive + tree : Set := node : A -> forest -> tree +with forest : Set := empty : forest + | cons : tree -> forest -> forest. + +Mutual Inductive Tree_Size : tree -> nat -> Prop := + Node_Size : (n:nat)(a:A)(f:forest)(Forest_Size f n) + ->(Tree_Size (node a f) (S n)) +with Forest_Size : forest -> nat -> Prop := + Empty_Size : (Forest_Size empty O) +| Cons_Size : (n,m:nat)(t:tree)(f:forest) + (Tree_Size t n) + ->(Forest_Size f m) + ->(Forest_Size (cons t f) (plus n m)). + +Hints Resolve Node_Size Empty_Size Cons_Size. +\end{coq_example*} + +Then, let us associate the two mutually dependent functions to compute +the size of a forest and a tree to the the following specification: + +\begin{coq_example*} +Theorem tree_size_prog : (t:tree){n:nat | (Tree_Size t n)}. + +Realizer [t:tree] +(Fix tree_size{ + tree_size [t:tree] : nat := let (a,f) = t in (S (forest_size f)) + with forest_size /1 : forest -> nat + := ([f:forest]Cases f of + empty => O + | (cons t f') => (plus (tree_size t) (forest_size f')) + end) + :: :: {(f:forest) {n:nat | (Forest_Size f n)}}} + t). +\end{coq_example*} + +It is necessary to add an annotation for the \verb=forest_size= +function. Indeed, the global specification corresponds to the +specification of the \verb=tree_size= function and the specification +of \verb=forest_size= cannot be automatically inferred from the +initial one. + +Then, the \verb=Program_all= tactic can be applied: +\begin{coq_example} +Program_all. +Save. +\end{coq_example} + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/Programs.tex b/doc/Programs.tex new file mode 100644 index 000000000..e92dd5931 --- /dev/null +++ b/doc/Programs.tex @@ -0,0 +1,931 @@ +\achapter{Proof of imperative programs} +\aauthor{Jean-Christophe Filliâtre} +\label{Addoc-programs} +\index{Imperative programs!proof of} +\comindex{Correctness} + +%%%%%%%%%%%%%%%% +% Introduction % +%%%%%%%%%%%%%%%% + +This chapter describes a new tactic +to prove the correctness and termination of imperative +programs annotated in a Floyd-Hoare logic style. +This tactic is provided in the \Coq\ module \texttt{Programs}, +which does not belong to the initial state of \Coq. So you must import +it when necessary, with the following command: +$$ +\mbox{\texttt{Require Programs.}} +$$ +If you want to use this tactic with the native-code version of \Coq, +you will have to run the version of \Coq\ with all the tactics, through +the command +$$ +\mbox{\texttt{coqtop -full}} +$$ +\emph{Be aware that this tactic is still very experimental}. + + +%%%%%%%%%%%%%%%%%%%%% +% comment ça marche % +%%%%%%%%%%%%%%%%%%%%% + +\asection{How it works} + +Before going on into details and syntax, let us give a quick overview +of how that tactic works. +Its behavior is the following: you give a +program annotated with logical assertions and the tactic will generate +a bundle of subgoals, called \emph{proof obligations}. Then, if you +prove all those proof obligations, you will establish the correctness and the +termination of the program. +The implementation currently supports traditional imperative programs +with references and arrays on arbitrary purely functional datatypes, +local variables, functions with call-by-value and call-by-variable +arguments, and recursive functions. + +Although it behaves as an implementation of Floyd-Hoare logic, it is not. +The idea of the underlying mechanism is to translate the imperative +program into a partial proof of a proposition of the kind +$$ +\forall \vec{x}. P(\vec{x}) + \Rightarrow \exists(\vec{y},v). Q(\vec{x},\vec{y},v) +$$ +where $P$ and $Q$ stand for the pre- and post-conditions of the +program, $\vec{x}$ and $\vec{y}$ the variables used and modified by +the program and $v$ its result. +Then this partial proof is given to the tactic \texttt{Refine} +(see~\ref{Refine}, page~\pageref{Refine}), which effect is to generate as many +subgoals as holes in the partial proof term. + +\medskip + +The syntax to invoke the tactic is the following: +$$ +\mbox{\tt Correctness} ~~ ident ~~ annotated\_program. +$$ +Notice that this is not exactly a \emph{tactic}, since it does not +apply to a goal. To be more rigorous, it is the combination of a +vernacular command (which creates the goal from the annotated program) +and a tactic (which partially solves it, leaving some proof +obligations to the user). + +Whereas \texttt{Correctness} is not a tactic, the following syntax is +available: +$$ +\mbox{\tt Correctness} ~~ ident ~~ annotated\_program ~ ; ~ tactic. +$$ +In that case, the given tactic is applied on any proof +obligation generated by the first command. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Syntaxe de programmes annotes % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\asection{Syntax of annotated programs} + +\asubsection{Programs} + +The syntax of programs is given in figure~\ref{fig:ProgramsSyntax}. +Basically, the programming language is a purely functional kernel +with an addition of references and arrays on purely functional values. +If you do not consider the logical assertions, the syntax coincide +with \ocaml\ syntax, except for elements of arrays which are written +$t[i]$. In particular, the dereference of a mutable variable $x$ is +written $!x$ and assignment is written \verb!:=! +(for instance, the increment of the variable $x$ will +be written \verb@x := !x + 1@). +Actually, that syntax does not really matters, since it would +be extracted later to real concrete syntax, in different programming +languages. + +\begin{figure}[htbp] + \begin{center} + \leavevmode +$$ +\begin{array}{lrl} + prog & ::= & \verb!{! ~ predicate ~ \verb!}! * + ~ statement ~ [ \verb!{! ~ predicate ~ \verb!}! ] \\ + + & & \\[0.1em] + + statement + & ::= & expression \\ + & | & identifier ~ \verb!:=! ~ prog \\ + & | & identifier ~ \verb![! ~ expression ~ \verb!]! + ~ \verb!:=! ~ prog \\ + & | & \verb!let! ~ identifier ~ \verb!=! ~ \verb!ref! ~ + prog ~ \verb!in! ~ prog \\ + & | & \verb!if! ~ prog ~ \verb!then! ~ prog + ~ [ \verb!else! ~ prog ] \\ + & | & \verb!while! ~ prog ~ \verb!do! + ~ loop\_annot ~ block ~ \verb!done! \\ + & | & \verb!begin! ~ block ~ \verb!end! \\ + & | & \verb!let! ~ identifier ~ \verb!=! ~ prog ~ + \verb!in! ~ prog \\ + & | & \verb!fun! ~ binders ~ \verb!->! ~ prog \\ + & | & \verb!let! ~ \verb!rec! ~ identifier ~ binder ~ \verb!:! + ~ value\_type \\ + & & ~~ \verb!{! ~ \verb!variant! ~ wf\_arg ~ \verb!}! + ~ \verb!=! ~ prog ~ [ \verb!in! ~ prog ] \\ + & | & \verb!(! ~ prog ~~ prog ~ \verb!)! \\ + + & & \\[1em] + + expression + & ::= & identifier \\ + & | & \verb@!@ ~ identifier \\ + & | & identifier ~ \verb![! ~ expression ~ \verb!]! \\ + & | & integer \\ + & | & \verb!(! ~ expression+ \verb!)! \\ + + & & \\[1em] + + block & ::= & block\_statement ~ [ ~ \verb!;! ~ block ~ ] \\ + + & & \\[0.1em] + + block\_statement + & ::= & prog \\ + & | & \verb!label! ~ identifier \\ + & | & \verb!assert! ~ \verb!{! ~ predicate ~ \verb!}! \\ + + & & \\[1em] + + binders & ::= & \verb!(! ~ identifier,\dots,identifier ~ \verb!:! + ~ value\_type ~ \verb!)! + \\ + + & & \\[1em] + + loop\_annot + & ::= & \verb!{! ~ \verb!invariant! ~ predicate ~ + \verb!variant! ~ wf\_arg ~ \verb!}! \\ + & & \\[0.1em] + + wf\_arg & ::= & cic\_term ~ [ \verb!for! ~ cic\_term ] \\ + + & & \\[0.1em] + + predicate & ::= & cci\_term ~ [ \verb!as! ~ identifier ] \\ + + \end{array} +$$ + \caption{Syntax of annotated programs} + \label{fig:ProgramsSyntax} + \end{center} +\end{figure} + + +\paragraph{Syntactic sugar.} + +\begin{itemize} + \item \textbf{Boolean expressions:} + + Boolean expressions appearing in programs (and in particular in + \kw{if} and \kw{while} tests) are arbitrary programs of type \texttt{bool}. + In order to make programs more readable, some syntactic sugar is + provided for the usual logical connectives and the usual order + relations over type \texttt{Z}, with the following syntax: + $$ + \begin{array}{lrl} + prog + & ::= & prog ~ \verb!and! ~ prog \\ + & | & prog ~ \verb!or! ~ prog \\ + & | & \verb!not! ~ prog \\ + & | & expression ~ order\_relation ~ expression \\[1em] + order\_relation + & ::= & \verb!>! ~|~ \verb!>=! ~|~ \verb!<! ~|~ \verb!<=! + ~|~ \verb!=! ~|~ \verb!<>! \\ + \end{array} + $$ + where the order relations have the strongest precedences, + \verb!not! has a stronger precedence than \verb!and!, + and \verb!and! a stronger precedence than \verb!or!. + + Order relations in other types, like \texttt{lt}, \texttt{le}, \dots in + type \texttt{nat}, should be explicited as described in the + paragraph about \emph{Boolean expressions}, page~\pageref{prog:booleans}. + + \item \textbf{Arithmetical expressions:} + + Some syntactic sugar is provided for the usual arithmetic operator + over type \texttt{Z}, with the following syntax: + $$ + \begin{array}{lrl} + prog + & ::= & prog ~ \verb!*! ~ prog \\ + & | & prog ~ \verb!+! ~ prog \\ + & | & prog ~ \verb!-! ~ prog \\ + & | & \verb!-! ~ prog + \end{array} + $$ + where the unary operator \texttt{-} has the strongest precedence, + and \texttt{*} a stronger precedence than \texttt{+} and \texttt{-}. + + Operations in other arithmetical types (such as type \texttt{nat}) + must be explicitly written as applications, like + \texttt{(plus~a~b)}, \texttt{(pred~a)}, etc. + + \item \texttt{if $b$ then $p$} is a shortcut for + \texttt{if $b$ then $p$ else tt}, where \texttt{tt} is the + constant of type \texttt{unit}; + + \item Values in type \texttt{Z} + may be directly written as integers : 0,1,12546,\dots + Negative integers are not recognized and must be written + as \texttt{(Zinv $x$)}; + + \item Multiple application may be written $(f~a_1~\dots~a_n)$, + which must be understood as left-associa\-tive + i.e. as $(\dots((f~a_1)~a_2)\dots~a_n)$. +\end{itemize} + + +\paragraph{Restrictions.} + +You can notice some restrictions with respect to real ML programs: +\begin{enumerate} + \item Binders in functions (recursive or not) are explicitly typed, + and the type of the result of a recursive function is also given. + This is due to the lack of type inference. + + \item Full expressions are not allowed on left-hand side of assignment, but + only variables. Therefore, you can not write +\begin{verbatim} + (if b then x else y) := 0 +\end{verbatim} + But, in most cases, you can rewrite + them into acceptable programs. For instance, the previous program + may be rewritten into the following one: +\begin{verbatim} + if b then x := 0 else y := 0 +\end{verbatim} +\end{enumerate} + + + +%%%%%%%%%%%%%%% +% Type system % +%%%%%%%%%%%%%%% + +\asubsection{Typing} + +The types of annotated programs are split into two kinds: the types of +\emph{values} and the types of \emph{computations}. Those two types +families are recursively mutually defined with the following concrete syntax: +$$ +\begin{array}{lrl} + value\_type + & ::= & cic\_term \\ + & | & {cic\_term} ~ \verb!ref! \\ + & | & \verb!array! ~ cic\_term ~ \verb!of! ~ cic\_term \\ + & | & \verb!fun! ~ \verb!(! ~ x \verb!:! value\_type ~ \verb!)!\!+ + ~ computation\_type \\ + & & \\ + computation\_type + & ::= & \verb!returns! ~ identifier \verb!:! value\_type \\ + & & [\verb!reads! ~ identifier,\ldots,identifier] + ~ [\verb!writes! ~ identifier,\ldots,identifier] \\ + & & [\verb!pre! ~ predicate] ~ [\verb!post! ~ predicate] \\ + & & \verb!end! \\ + & & \\ + predicate + & ::= & cic\_term \\ + & & \\ +\end{array} +$$ + +The typing is mostly the one of ML, without polymorphism. +The user should notice that: +\begin{itemize} + \item Arrays are indexed over the type \texttt{Z} of binary integers + (defined in the module \texttt{ZArith}); + + \item Expressions must have purely functional types, and can not be + references or arrays (but, of course, you can pass mutables to + functions as call-by-variable arguments); + + \item There is no partial application. +\end{itemize} + + +%%%%%%%%%%%%%%%%%% +% Specifications % +%%%%%%%%%%%%%%%%%% + +\asubsection{Specification} + +The specification part of programs is made of different kind of +annotations, which are terms of sort \Prop\ in the Calculus of Inductive +Constructions. + +Those annotations can refer to the values of the variables +directly by their names. \emph{There is no dereference operator ``!'' in +annotations}. Annotations are read with the \Coq\ parser, so you can +use all the \Coq\ syntax to write annotations. For instance, if $x$ +and $y$ are references over integers (in type \texttt{Z}), you can write the +following annotation +$$ +\mbox{\texttt{\{ `0 < x <= x+y` \}}} +$$ +In a post-condition, if necessary, you can refer to the value of the variable +$x$ \emph{before} the evaluation with the notation $x@$. +Actually, it is possible to refer to the value of a variable at any +moment of the evaluation with the notation $x@l$, +provided that $l$ is a \emph{label} previously inserted in your program +(see below the paragraph about labels). + +You have the possibility to give some names to the annotations, with +the syntax +$$ +\texttt{\{ \emph{annotation} as \emph{identifier} \}} +$$ +and then the annotation will be given this name in the proof +obligations. +Otherwise, fresh names are given automatically, of the kind +\texttt{Post3}, \texttt{Pre12}, \texttt{Test4}, etc. +You are encouraged to give explicit names, in order not to have to +modify your proof script when your proof obligations change (for +instance, if you modify a part of the program). + + +\asubsubsection{Pre- and post-conditions} + +Each program, and each of its sub-programs, may be annotated by a +pre-condition and/or a post-condition. +The pre-condition is an annotation about the values of variables +\emph{before} the evaluation, and the post-condition is an annotation +about the values of variables \emph{before} and \emph{after} the +evaluation. Example: +$$ +\mbox{\texttt{\{ `0 < x` \} x := (Zplus !x !x) \{ `x@ < x` \}}} +$$ +Moreover, you can assert some properties of the result of the evaluation +in the post-condition, by referring to it through the name \emph{result}. +Example: +$$ +\mbox{\texttt{(Zs (Zplus !x !x)) \{ (Zodd result) \}}} +$$ + + +\asubsubsection{Loops invariants and variants} + +Loop invariants and variants are introduced just after the \kw{do} +keyword, with the following syntax: +$$ +\begin{array}{l} + \kw{while} ~ B ~ \kw{do} \\ + ~~~ \{ ~ \kw{invariant} ~ I ~~~ \kw{variant} ~ \phi ~ \kw{for} ~ R ~ + \} \\ + ~~~ block \\ + \kw{done} +\end{array} +$$ + +The invariant $I$ is an annotation about the values of variables +when the loop is entered, since $B$ has no side effects ($B$ is a +purely functional expression). Of course, $I$ may refer to values of +variables at any moment before the entering of the loop. + +The variant $\phi$ must be given in order to establish the termination of +the loop. The relation $R$ must be a term of type $A\rightarrow +A\rightarrow\Prop$, where $\phi$ is of type $A$. +When $R$ is not specified, then $\phi$ is assumed to be of type +\texttt{Z} and the usual order relation on natural number is used. + + +\asubsubsection{Recursive functions} + +The termination of a recursive function is justified in the same way as +loops, using a variant. This variant is introduced with the following syntax +$$ +\kw{let} ~ \kw{rec} ~ f ~ (x_1:V_1)\dots(x_n:V_n) : V + ~ \{ ~ \kw{variant} ~ \phi ~ \kw{for} ~ R ~ \} = prog +$$ +and is interpreted as for loops. Of course, the variant may refer to +the bound variables $x_i$. +The specification of a recursive function is the one of its body, $prog$. +Example: +$$ +\kw{let} ~ \kw{rec} ~ fact ~ (x:Z) : Z ~ \{ ~ \kw{variant} ~ x \} = + \{ ~ x\ge0 ~ \} ~ \dots ~ \{ ~ result=x! ~ \} +$$ + + +\asubsubsection{Assertions inside blocks} + +Assertions may be inserted inside blocks, with the following syntax +$$ +\kw{begin} ~ block\_statements \dots; ~ \kw{assert} ~ \{ ~ P ~ \}; + ~ block\_statements \dots ~ \kw{end} +$$ +The annotation $P$ may refer to the values of variables at any labels +known at this moment of evaluation. + + +\asubsubsection{Inserting labels in your program} + +In order to refer to the values of variables at any moment of +evaluation of the program, you may put some \emph{labels} inside your +programs. Actually, it is only necessary to insert them inside blocks, +since this is the only place where side effects can appear. The syntax +to insert a label is the following: +$$ +\kw{begin} ~ block\_statements \dots; ~ \kw{label} ~ L; + ~ block\_statements \dots ~ \kw{end} +$$ +Then it is possible to refer to the value of the variable $x$ at step +$L$ with the notation $x@L$. + +There is a special label $0$ which is automatically inserted at the +beginning of the program. Therefore, $x@0$ will always refer to the +initial value of the variable $x$. + +\medskip + +Notice that this mechanism allows the user to get rid of the so-called +\emph{auxiliary variables}, which are usually widely used in +traditional frameworks to refer to previous values of variables. + + +%%%%%%%%%%%% +% booléens % +%%%%%%%%%%%% + +\asubsubsection{Boolean expressions}\label{prog:booleans} + +As explained above, boolean expressions appearing in \kw{if} and +\kw{while} tests are arbitrary programs of type \texttt{bool}. +Actually, there is a little restriction: a test can not do some side +effects. +Usually, a test if annotated in such a way: +$$ + B ~ \{ \myifthenelse{result}{T}{F} \} +$$ +(The \textsf{if then else} construction in the annotation is the one +of \Coq\ !) +Here $T$ and $F$ are the two propositions you want to get in the two +branches of the test. +If you do not annotate a test, then $T$ and $F$ automatically become +$B=\kw{true}$ and $B=\kw{false}$, which is the usual annotation in +Floyd-Hoare logic. + +But you should take advantages of the fact that $T$ and $F$ may be +arbitrary propositions, or you can even annotate $B$ with any other +kind of proposition (usually depending on $result$). + +As explained in the paragraph about the syntax of boolean expression, +some syntactic sugar is provided for usual order relations over type +\texttt{Z}. When you write $\kw{if} ~ x<y ~ \dots$ in your program, +it is only a shortcut for $\kw{if} ~ (\texttt{Z\_lt\_ge\_bool}~x~y) ~ \dots$, +where \texttt{Z\_lt\_ge\_bool} is the proof of +$\forall x,y:\texttt{Z}. \exists b:\texttt{bool}. + (\myifthenelse{b}{x<y}{x\ge y})$ +i.e. of a program returning a boolean with the expected post-condition. +But you can use any other functional expression of such a type. +In particular, the Programs standard library comes +with a bunch of decidability theorems on type \texttt{nat}: +$$ +\begin{array}{ll} + zerop\_bool & : \forall n:\kw{nat}.\exists b:\texttt{bool}. + \myifthenelse{b}{n=0}{0<n} \\ + nat\_eq\_bool & : \forall n,m:\kw{nat}.\exists b:\texttt{bool}. + \myifthenelse{b}{n=m}{n\not=m} \\ + le\_lt\_bool & : \forall n,m:\kw{nat}.\exists b:\texttt{bool}. + \myifthenelse{b}{n\le m}{m<n} \\ + lt\_le\_bool & : \forall n,m:\kw{nat}.\exists b:\texttt{bool}. + \myifthenelse{b}{n<m}{m\le n} \\ +\end{array} +$$ +which you can combine with the logical connectives. + +It is often the case that you have a decidability theorem over some +type, as for instance a theorem of decidability of equality over some +type $S$: +$$ +S\_dec : (x,y:S)\sumbool{x=y}{\neg x=y} +$$ +Then you can build a test function corresponding to $S\_dec$ using the +operator \texttt{bool\_of\_sumbool} provided with the +\texttt{Prorgams} module, in such a way: +$$ +\texttt{Definition} ~ S\_bool ~ \texttt{:=} + [x,y:S](\texttt{bool\_of\_sumbool} ~ ? ~ ? ~ (S\_dec ~ x ~ y)) +$$ +Then you can use the test function $S\_bool$ in your programs, +and you will get the hypothesis $x=y$ and $\neg x=y$ in the corresponding +branches. +Of course, you can do the same for any function returning some result +in the constructive sum $\sumbool{A}{B}$. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% variables locales et globales % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\asection{Local and global variables} + +\asubsection{Global variables} +\comindex{Global Variable} + +You can declare a new global variable with the following command +$$ +\mbox{\texttt{Global Variable}} ~~ x ~ : ~ value\_type. +$$ +where $x$ may be a reference, an array or a function. +\Example +\begin{verbatim} +Parameter N : Z. +Global Variable x : Z ref. +Correctness foo { `x < N` } begin x := (Zmult 2 !x) end { `x < 2*N` }. +\end{verbatim} + +\comindex{Show Programs} +Each time you complete a correctness proof, the corresponding program is +added to the programs environment. You can list the current programs +environment with the command +$$ +\mbox{\texttt{Show Programs.}} +$$ + + +\asubsection{Local variables} + +Local variables are introduced with the following syntax +$$ +\mbox{\texttt{let}} ~ x ~ = ~ \mbox{\texttt{ref}} ~ e_1 +~ \mbox{\texttt{in}} ~ e_2 +$$ +where the scope of $x$ is exactly the program $e_2$. +Notice that, as usual in ML, local variables must be +initialized (here with $e_1$). + +When specifying a program including local variables, you have to take +care about their scopes. Indeed, the following two programs are not +annotated in the same way: +\begin{itemize} + \item $\kw{let} ~ x = e_1 ~ \kw{in} ~ e_2 ~ \spec{Q}$ \\ + The post-condition $Q$ applies to $e_2$, and therefore $x$ may + appear in $Q$; + + \item $(\kw{let} ~ x = e_1 ~ \kw{in} ~ e_2) ~ \spec{Q}$ \\ + The post-condition $Q$ applies to the whole program, and therefore + the local variable $x$ may \emph{not} appear in $Q$ (it is beyond + its scope). +\end{itemize} + + +%%%%%%%%%%%%%%%%% +% Function call % +%%%%%%%%%%%%%%%%% + +\asection{Function call} + +Still following the syntax of ML, the function application is written +$(f ~ a_1 ~ \ldots ~ a_n)$, where $f$ is a function and the $a_i$'s +its arguments. Notice that $f$ and the $a_i$'s may be annotated +programs themselves. + +In the general case, $f$ is a function already specified (either with +\texttt{Global Variable} or with a proof of correctness) and has a +pre-condition $P_f$ and a post-condition $Q_f$. + +As expected, a proof obligation is generated, which correspond to +$P_f$ applied to the values of the arguments, once they are evaluated. + +Regarding the post-condition of $f$, there are different possible cases: +\begin{itemize} + \item either you did not annotate the function call, writing directly + $$(f ~ a_1 ~ \ldots ~ a_n)$$ + and then the post-condition of $f$ is added automatically + \emph{if possible}: indeed, if some arguments of $f$ make side-effects + this is not always possible. In that case, you have to put a + post-condition to the function call by yourself; + + \item or you annotated it with a post-condition, say $Q$: + $$(f ~ a_1 ~ \ldots ~ a_n) ~ \spec{Q}$$ + then you will have to prove that $Q$ holds under the hypothesis that + the post-condition $Q_f$ holds (where both are + instantiated by the results of the evaluation of the $a_i$). + Of course, if $Q$ is exactly the post-condition of $f$ then + the corresponding proof obligation will be automatically + discharged. +\end{itemize} + + +%%%%%%%%%%%% +% Libraries % +%%%%%%%%%%%% + +\asection{Libraries} +\index{Imperative programs!libraries} + +The tactic comes with some libraries, useful to write programs and +specifications. +The first set of libraries is automatically loaded with the module +\texttt{Programs}. Among them, you can find the modules: +\begin{description} + \item[ProgWf]: this module defines a family of relations $Zwf$ on type + \texttt{Z} by + $$(Zwf ~ c) = \lambda x,y. c\le x \land c \le y \land x < y$$ + and establishes that this relation is well-founded for all $c$ + (lemma \texttt{Zwf\_well\_founded}). This lemma is automatically + used by the tactic \texttt{Correctness} when necessary. + When no relation is given for the variant of a loop or a recursive + function, then $(Zwf~0)$ is used \emph{i.e.} the usual order + relation on positive integers. + + \item[Arrays]: this module defines an abstract type \texttt{array} + for arrays, with the corresponding operations \texttt{new}, + \texttt{access} and \texttt{store}. Access in a array $t$ at index + $i$ may be written \texttt{$t$\#[$i$]} in \Coq, and in particular + inside specifications. + This module also provides some axioms to manipulate arrays + expression, among which \texttt{store\_def\_1} and + \texttt{store\_def\_2} allow you to simplify expressions of the + kind \texttt{(access (store $t$ $i$ $v$) $j$)}. +\end{description} + +\noindent Other useful modules, which are not automatically loaded, are the +following: +\begin{description} + \item[Exchange]: this module defines a predicate \texttt{(exchange + $t$ $t'$ $i$ $j$)} which means that elements of indexes $i$ and + $j$ are swapped in arrays $t$ and $t'$, and other left unchanged. + This modules also provides some lemmas to establish this property + or conversely to get some consequences of this property. + + \item[Permut]: this module defines the notion of permutation between + two arrays, on a segment of the arrays (\texttt{sub\_permut}) or + on the whole array (\texttt{permut}). + Permutations are inductively defined as the smallest equivalence + relation containing the transpositions (defined in the module + \texttt{Exchange}). + + \item[Sorted]: this module defines the property for an array to be + sorted, on the whole array (\texttt{sorted\_array}) or on a segment + (\texttt{sub\_sorted\_array}). It also provides a few lemmas to + establish this property. +\end{description} + + + +%%%%%%%%%%%%%% +% Extraction % +%%%%%%%%%%%%%% + +\asection{Extraction} +\index{Imperative programs!extraction of} + +Once a program is proved, one usually wants to run it, and that's why +this implementation comes with an extraction mechanism. +For the moment, there is only extraction to \ocaml\ code. +This functionality is provided by the following module: +$$ +\mbox{\texttt{Require ProgramsExtraction.}} +$$ +This extraction facility extends the extraction of functional programs +(see chapter~\ref{CamlHaskellExtraction}), on which it is based. +Indeed, the extraction of functional terms (\Coq\ objects) is first +performed by the module \texttt{Extraction}, and the extraction of +imperative programs comes after. +Therefore, we have kept the same syntax as for functional terms: +$$ +\mbox{\tt Write Caml File "\str" [ \ident$_1$ \dots\ \ident$_n$ ].} +$$ +where \str\ is the name given to the file to be produced (the suffix +{\tt .ml} is added if necessary), and \ident$_1$ \dots\ \ident$_n$ the +names of the objects to be extracted. +That list may contain functional and imperative objects, and does not need +to be exhaustive. + +Of course, you can use the extraction facilities described in +chapter~\ref{CamlHaskellExtraction}, namely the \texttt{ML Import}, +\texttt{Link} and \texttt{Extract} commands. + + +\paragraph{The case of integers} +There is no use of the \ocaml\ native integers: indeed, it would not be safe +to use the machine integers while the correctness proof is done +with unbounded integers (\texttt{nat}, \texttt{Z} or whatever type). +But since \ocaml\ arrays are indexed over the type \texttt{int} +(the machine integers) arrays indexes are converted from \texttt{Z} +to \texttt{int} when necessary (the conversion is very fast: due +to the binary representation of integers in type \texttt{Z}, it +will never exceed thirty elementary steps). + +And it is also safe, since the size of a \ocaml\ array can not be greater +than the maximum integer ($2^{30}-1$) and since the correctness proof +establishes that indexes are always within the bounds of arrays +(Therefore, indexes will never be greater than the maximum integer, +and the conversion will never produce an overflow). + + +%%%%%%%%%%%% +% Examples % +%%%%%%%%%%%% + +\asection{Examples}\label{prog:examples} + +\asubsection{Computation of $X^n$} + +As a first example, we prove the correctness of a program computing +$X^n$ using the following equations: +$$ +\left\{ +\begin{array}{lcl} +X^{2n} & = & (X^n)^2 \\ +X^{2n+1} & = & X \times (X^n)^2 +\end{array} +\right. +$$ +If $x$ and $n$ are variables containing the input and $y$ a variable that will +contain the result ($x^n$), such a program may be the following one: +\begin{center} + \begin{minipage}{8cm} + \begin{tabbing} + AA\=\kill + $m$ := $!x$ ; $y$ := $1$ ; \\ + \kw{while} $!n \not= 0$ \kw{do} \\ + \> \kw{if} $(odd ~ !n)$ \kw{then} $y$ := $!y \times !m$ ;\\ + \> $m$ := $!m \times !m$ ; \\ + \> $n$ := $!n / 2$ \\ + \kw{done} \\ + \end{tabbing} + \end{minipage} +\end{center} + + +\paragraph{Specification part.} + +Here we choose to use the binary integers of \texttt{ZArith}. +The exponentiation $X^n$ is defined, for $n \ge 0$, in the module +\texttt{Zpower}: +\begin{coq_example*} +Require ZArith. +Require Zpower. +\end{coq_example*} + +In particular, the module \texttt{ZArith} loads a module \texttt{Zmisc} +which contains the definitions of the predicate \texttt{Zeven} and +\texttt{Zodd}, and the function \texttt{Zdiv2}. +This module \texttt{ProgBool} also contains a test function +\texttt{Zeven\_odd\_bool} of type +$\forall n. \exists b. \myifthenelse{b}{(Zeven~n)}{(Zodd~n)}$ +derived from the proof \texttt{Zeven\_odd\_dec}, +as explained in section~\ref{prog:booleans}: + +\begin{coq_eval} +Require Ring. +\end{coq_eval} + + +\paragraph{Correctness part.} + +Then we come to the correctness proof. We first import the \Coq\ +module \texttt{Programs}: +\begin{coq_example*} +Require Programs. +\end{coq_example*} +\begin{coq_eval} +Definition Zsquare := [n:Z](Zmult n n). +Definition Zdouble := [n:Z]`2*n`. +\end{coq_eval} + +Then we introduce all the variables needed by the program: +\begin{coq_example*} +Parameter x : Z. +Global Variable n,m,y : Z ref. +\end{coq_example*} + +At last, we can give the annotated program: +\begin{coq_example} +Correctness i_exp + { `n >= 0` } + begin + m := x; y := 1; + while !n > 0 do + { invariant (Zpower x n@0)=(Zmult y (Zpower m n)) /\ `n >= 0` + variant n } + (if not (Zeven_odd_bool !n) then y := (Zmult !y !m)) + { (Zpower x n@0) = (Zmult y (Zpower m (Zdouble (Zdiv2 n)))) }; + m := (Zsquare !m); + n := (Zdiv2 !n) + done + end + { y=(Zpower x n@0) } +. +\end{coq_example} + +The proof obligations require some lemmas involving \texttt{Zpower} and +\texttt{Zdiv2}. You can find the whole proof in the \Coq\ standard +library (see below). +Let us make some quick remarks about this program and the way it was +written: +\begin{itemize} + \item The name \verb!n@0! is used to refer to the initial value of + the variable \verb!n!, as well inside the loop invariant as in + the post-condition; + + \item Purely functional expressions are allowed anywhere in the + program and they can use any purely informative \Coq\ constants; + That is why we can use \texttt{Zmult}, \texttt{Zsquare} and + \texttt{Zdiv2} in the programs even if they are not other functions + previously introduced as programs. +\end{itemize} + + +\asubsection{A recursive program} + +To give an example of a recursive program, let us rewrite the previous +program into a recursive one. We obtain the following program: +\begin{center} + \begin{minipage}{8cm} + \begin{tabbing} + AA\=AA\=AA\=\kill + \kw{let} \kw{rec} $exp$ $x$ $n$ = \\ + \> \kw{if} $n = 0$ \kw{then} \\ + \> \> 1 \\ + \> \kw{else} \\ + \> \> \kw{let} $y$ = $(exp ~ x ~ (n/2))$ \kw{in} \\ + \> \> \kw{if} $(even ~ n)$ \kw{then} $y\times y$ + \kw{else} $x\times (y\times y)$ \\ + \end{tabbing} + \end{minipage} +\end{center} + +This recursive program, once it is annotated, is given to the +tactic \texttt{Correctness}: +\begin{coq_eval} +Reset n. +\end{coq_eval} +\begin{coq_example} +Correctness r_exp + let rec exp (x:Z) (n:Z) : Z { variant n } = + { `n >= 0` } + (if n = 0 then + 1 + else + let y = (exp x (Zdiv2 n)) in + (if (Zeven_odd_bool n) then + (Zmult y y) + else + (Zmult x (Zmult y y))) { result=(Zpower x n) } + ) + { result=(Zpower x n) } +. +\end{coq_example} + +You can notice that the specification is simpler in the recursive case: +we only have to give the pre- and post-conditions --- which are the same +as for the imperative version --- but there is no annotation +corresponding to the loop invariant. +The other two annotations in the recursive program are added for the +recursive call and for the test inside the \textsf{let in} construct +(it can not be done automatically in general, +so the user has to add it by himself). + + +\asubsection{Other examples} + +You will find some other examples with the distribution of the system +\Coq, in the sub-directory \verb!tactics/programs/EXAMPLES! of the +\Coq\ standard library. Those examples are mostly programs to compute +the factorial and the exponentiation in various ways (on types \texttt{nat} +or \texttt{Z}, in imperative way or recursively, with global +variables or as functions, \dots). + +There are also some bigger correctness developments in the +\Coq\ contributions, which are available on the web page +\verb!coq.inria.fr/contribs!. +for the moment, you can find: +\begin{itemize} + \item A proof of \emph{insertion sort} by Nicolas Magaud, ENS Lyon; + \item A proof of \emph{quicksort} and \emph{find} by the author. +\end{itemize} + + +%%%%%%%%%%%%%%% +% BUG REPORTS % +%%%%%%%%%%%%%%% + +\asection{Bugs} + +\begin{itemize} + \item There is no discharge mechanism for programs; so you + \emph{cannot} do a program's proof inside a section (actually, + you can do it, but your program will not exist anymore after having + closed the section). +\end{itemize} + +Surely there are still many bugs in this implementation. +Please send bug reports to \textsf{Jean-Christophe.Filliatre$@$lri.fr}. +Don't forget to send the version of \Coq\ used (given by +\texttt{coqtop -v}) and a script producing the bug. + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/README b/doc/README new file mode 100755 index 000000000..832e6167c --- /dev/null +++ b/doc/README @@ -0,0 +1,45 @@ +You can get the whole documentation of Coq in the tar file all-ps-docs.tar. + +You can also get separately each document. The documentation of Coq +V6.3.1 is divided into the following documents : + + * Tutorial.ps: An introduction to the use of the Coq Proof Assistant; + + * Reference-Manual-base.ps: 215 pp., includes + + - the description of Gallina, the language of Coq + - the description of the Vernacular, the commands of Coq + - the description of each tactic + - chapters about Grammar/Syntax extentions and Writing tactics + - index on tactics, commands and error messages + + * Reference-Manual-addendum.ps, 75 pp., includes more detailed + explanations and examples about the following topics: + + - the extended Cases (C.Cornes) + - the Coercions (A. Saïbi) + - the tactic Omega (P. Crégut) + - printing proofs in natural language (Y. Coscoy) + - the tactic Ring (S. Boutin and P. Loiseleur) + - the Program tactic (C. Parent) + - the Correctness tactic (J.-C. Filliâtre) + - the extraction features (J.-C. Filliâtre) + + Index, page and chapter numbers are shared by the two documents, in + order to make cross-references possible. There is also a on the ftp + server a Postscript file Reference-Manual-all.ps that contains the two + documents (base and addendum). + + * Library.ps: A description of the Coq standard library; + + * Changes.ps: A description of the differences between the + versions V6.3 and V6.3.1; + + * rectypes.ps : A tutorial on recursive types by Eduardo Gimenez + +Documentation is also available in the DVI format (you can get the DVI docs +separately or in the tar file all-dvi.docs.tar). + +The Reference Manual and the Tutorial are also available in HTML format +(online at http://coq.inria.fr or by ftp in the file doc-html.tar.gz). + diff --git a/doc/Recursive-Definition.tex b/doc/Recursive-Definition.tex new file mode 100755 index 000000000..77774d9fa --- /dev/null +++ b/doc/Recursive-Definition.tex @@ -0,0 +1,251 @@ +\documentstyle[]{article} +\input{title} + +\newcommand{\xx}{\noindent} +\newcommand{\Coq}{{\sf Coq}} + +\begin{document} + +\coverpage{Users friendly {\tt Recursive Definition}}{Pascal MANOURY} + +This command allows to define functions in +the following syntax : +\begin{verbatim} +Recursive Definition f [X1:U1;..;Xk:Uk] : T1-> .. -> Tn -> T := + p11 .. p1n => t1 +... +|pm1 .. pmn => tm. +\end{verbatim} +This definition schema must be understood as : +\begin{itemize} +\item {\tt f} is the name of the constant we want +to define; +\item {\tt (X1:U1)..(Xk:Uk) T1-> .. -> Tn -> T} +is its intended type; +\item {\tt p11 .. p1n => t1 | ... |pm1 .. pmn => tm.} +describe its beha\-viour in terms of patterns. +We +call the {\sl patterns clauses} this part of the {\tt Recursive Definition}. +\end{itemize} +The semantics of the {\tt Recursive Definition} +is to +define the new constant {\tt f} as a term (say {\tt F}) of +the intended type providing that {\tt F} has the intended +computational behavior expressed in the {\sl patterns +clauses}. Moreover, a {\tt Recursive Definition} states and +proves all equational theorems corresponding to {\sl +patterns clauses}. In other words, a {\tt Recursive Definition} is +equivalent to : +\begin{verbatim} +Definition f : (X1:U1)..(Xk:Uk) T1-> .. -> Tn -> T := F. +Theorem f_eq1 : (X1:U1)..(Xk:Uk)(x11:V11)..(x1l:V1l)(F X1 .. Xk p11 .. p1n)=t1. +Intros; Unfold F; Simpl; Trivial. Save. +... +Theorem f_eqm : (X1:U1)..(Xk:Uk)(xm1:Vm1)..(xml:Vml)(F X1 .. Xk pm1 .. pmn)=tm. +Intros; Unfold F; Simpl; Trivial. Save. +\end{verbatim} +For instance, one can write : +\begin{coq_example} +Recursive Definition Ack : nat -> nat -> nat := + O m => (S m) + |(S n) O => (Ack n (S O)) + |(S n) (S m) => (Ack n (Ack (S n) m)). +\end{coq_example} + +Unfortunately, the problem of finding a term (of \Coq) +satisfying a set of {\sl patterns clauses} does not always have a +solution, as shown by the following example~:\\ +\centerline {\tt Recursive Definition fix : +nat -> nat := n => (fix n).} +The point is that, in \Coq, any term {\tt F} of type {\tt +nat -> nat} represents a function which always terminates +and it is easy to see that the function {\tt fix} never +terminates. This general property of \Coq's terms is called +{\it strong normalization}. + +\xx +The fact that a syntactically correct {\tt Recursive +Definition} as the one of {\tt fix} does not correspond to any +term in \Coq~ points out that we cannot content with the {\it +syntactical level} of the declaration to obtain a term, but we +have to lift up onto the {\it logical level} to ensure that +the aimed function satisfies such a strong property as +termination. And here comes the difficulty, since the termination +problem is known to be undecidable in general. + +\xx +In fact, termination is the main logical property we +have to face with. Then the main job of the {\tt Recursive +Definition} is to build a proof of {\tt (X1:U1)..(Xk:Uk) +T1-> .. -> Tn -> T} understood as a termination proof of the +aimed function.\\ +Let's see how it works on the Ackermann's function example +: +\begin{coq_eval} +Restore State Initial. +\end{coq_eval} +\begin{coq_example} +Theorem Ack : nat -> nat -> nat. +Intro n; Elim n. +Intro m; Exact (S m). +Intros p Ack_n m; Elim m. +Exact (Ack_n (S O)). +Intros q Ack_Sn_m; Exact (Ack_n Ack_Sn_m). +Save. +\end{coq_example} +One can check that the term {\tt Ack} ({\it eg} : the above +proof of {\tt nat -> nat -> nat}) actually satisfies +the intended {\sl patterns clauses} of Ackermann's +function. + +\xx +Such a proof is {\em automatically} synthesized by a +{specialized strategy} which was originally designed for the +{\sf ProPre} programming language. It has been adapted for +the \Coq's framework. For a short description of the {\sf +ProPre} programming language, we refer the reader to +\cite{MPSI}. For details +concerning the original proof search strategy, we refer the +reader to \cite{MSAR}. For theoretical settings of the +method involved in {\sf ProPre}, we refer the reader to +\cite{KRPA} and \cite{PARI}. + +\xx +We list bellow some correct and incorrect usages of +the {\tt Recursive Definition} feature. + +\subsection*{Correct {\tt Recursive Definition}'s} +\begin{coq_example*} +Recursive Definition IfSet [X:Set] : bool -> X -> X -> X := + true x y => x + |false x y => y. +Recursive Definition equal_nat : nat -> nat -> bool := + O O => true + |O (S m) => false + |(S n) O => false + |(S n) (S m) => (equal_nat n m). +Recursive Definition less_equal : nat -> nat -> bool := + O m => true + |(S n) O => false + |(S n) (S m) => (less_equal n m). +Inductive Set bintree := + Le : bintree + |Br : nat -> bintree -> bintree -> bintree. +Recursive Definition ins_bsr [n:nat] : bintree -> bintree := + Le => (Br n Le Le) + |(Br m a1 a2) + => (IfSet bintree (less_equal n m) (Br m (ins_bsr n a1) a2) + (Br m a1 (ins_bsr n a2))). +Inductive list [X:Set] : Set := + Nil : (list X) + |Cons : X -> (list X) -> (list X). +Recursive Definition append [X:Set;ys:(list X)] : (list X) -> (list X) := + (Nil X) => ys + |(Cons X x xs) => (Cons X x (append X ys xs)). +Recursive Definition soml : (list nat) -> nat := + (Nil nat) => O + |(Cons nat O x) => (soml x) + |(Cons nat (S n) x) => (S (soml (Cons nat n x))). +Recursive Definition sorted_list : (list nat) -> Prop := + (Nil nat) => True + |(Cons nat n (Nil nat)) => True +|(Cons nat n (Cons nat m x)) + => (<bool>(less_equal n m)=true) /\ (sorted_list (Cons nat m x)). +\end{coq_example*} + +\subsection*{Incorrect {\tt Recursive Definition}'s} +\begin{coq_example} +Recursive Definition equal_list : (list nat) -> (list nat) -> bool := + (Nil nat) (Nil nat) => true + |(Nil nat) (Cons nat n y) => false + |(Cons nat n x) (Nil nat) => false + |(Cons nat n x) (Cons nat n y) => (equal_list x y). +\end{coq_example} +As explains the error message, a same pattern variable can't be used +more than one time. +\begin{coq_example} +Recursive Definition min : nat -> nat -> nat := + O m => m + |n O => n + |(S n) (S m) => (S (min n m)). +\end{coq_example} +We do not allow the various left members of {\sl patterns clauses} to +overlap. +\begin{coq_example} +Recursive Definition wrong_equal : nat -> nat -> bool := + O O => true + |(S n) (S m) => (wrong_equal n m). +\end{coq_example} +As we need to prove that the function is totally defined, we need an +exhaustive pattern matching of the inputs. +\begin{coq_example} +Recursive Definition div2 : nat -> nat := + O => O + |(S O) => O + |(S (S n)) => (S (div2 n)). +\end{coq_example} +The strategy makes use of structural induction to search a proof of +{\tt nat -> nat}, then it can only accept arguments decreasing in one +step ({\it eg} from {\tt (S n)} to {\tt n}) which is not the case +here. +\begin{coq_example} +Recursive Definition wrong_fact : nat -> nat := + n => (IfSet nat (equal_nat n O) (S O) (mult n (wrong_fact (pred n)))). +\end{coq_example} +This error comes from the fact that the strategy doesn't recognize +that the {\tt IfSet} is used as matching on naturals and that, when +{\tt n} is not {\tt O}, {\tt (pred n)} is less than {\tt n}. Indeed, +matching must be explicit and decreasing too. +\begin{coq_example} +Recursive Definition heap_merge : bintree -> bintree -> bintree := + Le b => b + |(Br n a1 a2) Le => (Br n a1 a2) + |(Br n a1 a2) (Br m b1 b2) + => (IfSet bintree + (less_equal n m) + (Br n (heap_merge a1 a2) (Br m b1 b2)) + (Br m (Br n a1 a2) (heap_merge b1 b2))). +\end{coq_example} +This failure of the strategy is due to the fact than with simple +structural induction one can't get any induction hypothesis for both +inductive calls {\tt (heap\_merge a1 a2)} and {\tt (heap\_merge b1 + b2)}. + + +\begin{thebibliography}{9999} +\bibitem{KRPA} J.L Krivine, M. Parigot + {\it Programming with proofs} ; in SCT 87 (1987), +Wendish-Rietz ; in EIK 26 (1990) pp 146-167. + +\bibitem{MPSI} P. Manoury, M. Parigot, M. Simonot {\it {\sf +ProPre} : a programming language with proofs} ; in +proceedings LPAR 92, LNAI 624. + +\bibitem{MSTH} P. Manoury and M. Simonot {\it Des preuves +de totalit\'e de fonctions comme synth\`ese de +programmes} ; Phd Thesis, Universit\'e Paris 7, December +1992. + +\bibitem{MSAR} P. Manoury and M. Simonot {\it +Automatizing termination proof of recursively defined +functions} ; to appear in TCS. + +\bibitem{PARI} M. Parigot {\it Recursive programming with +proofs} ; in TCS 94 (1992) pp 335-356. + +\bibitem{PAUL} C. Paulin-Mohring {\it Inductive +Definitions in the System Coq - Rules and properties} ; +proceedings TLCA 93, LNCS 664 (1993). + +\bibitem{WERN} B. Werner {\it Une th\'eorie des +constructions inductives} ; Phd Thesis, Universit\'e Paris +7, May 1994. + +\end{thebibliography} + +\end{document} + + + + +% $Id$ diff --git a/doc/RefMan-add.tex b/doc/RefMan-add.tex new file mode 100755 index 000000000..d04d1468f --- /dev/null +++ b/doc/RefMan-add.tex @@ -0,0 +1,54 @@ +\chapter{List of additional documentation}\label{Addoc} + +\section{Tutorials}\label{Tutorial} +A companion volume to this reference manual, the \Coq\ Tutorial, is +aimed at gently introducing new users to developing proofs in \Coq\ +without assuming prior knowledge of type theory. In a second step, the +user can read also the tutorial on recursive types (document {\tt +RecTutorial.ps}). + +\section{The \Coq\ standard library}\label{Addoc-library} +A brief description of the \Coq\ standard library is given in the additional +document {\tt Library.dvi}. + +\section{Installation and un-installation procedures}\label{Addoc-install} +A \verb!INSTALL! file in the distribution explains how to install +\Coq. + +\section{{\tt Extraction} of programs}\label{Addoc-extract} +{\tt Extraction} is a package offering some special facilities to +extract ML program files. It is described in the separate document +{\tt Extraction.dvi} +\index{Extraction of programs} + +\section{Proof printing in {\tt Natural} language}\label{Addoc-natural} +{\tt Natural} is a tool to print proofs in natural language. +It is described in the separate document {\tt Natural.dvi}. +\index{Natural@{\tt Print Natural}} +\index{Printing in natural language} + +\section{The {\tt Omega} decision tactic}\label{Addoc-omega} +{\bf Omega} is a tactic to automatically solve arithmetical goals in +Presburger arithmetic (i.e. arithmetic without multiplication). +It is described in the separate document {\tt Omega.dvi}. +\index{Omega@{\tt Omega}} + +\section{Simplification on rings}\label{Addoc-polynom} +A documentation of the package {\tt polynom} (simplification on rings) +can be found in the document {\tt Polynom.dvi} +\index{Polynom@{\tt Polynom}} +\index{Simplification on rings} + +%\section{Anomalies}\label{Addoc-anomalies} +%The separate document {\tt Anomalies.*} gives a list of known +%anomalies and bugs of the system. Before communicating us an +%anomalous behavior, please check first whether it has been already +%reported in this document. + +% $Id$ + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/RefMan-cas.tex b/doc/RefMan-cas.tex new file mode 100755 index 000000000..f48242fae --- /dev/null +++ b/doc/RefMan-cas.tex @@ -0,0 +1,671 @@ +%\documentstyle[11pt,../tools/coq-tex/coq,fullpage]{article} + +%\pagestyle{plain} + +%\begin{document} +%\nocite{Augustsson85,wadler87,HuetLevy79,MaSi94,maranget94,Laville91,saidi94,dowek93,Leroy90,puel-suarez90} + +%\input{title} +%\input{macros} +%\coverpage{The Macro \verb+Cases+}{Cristina Cornes} +%\pagestyle{plain} +\chapter{The Macro {\tt Cases}}\label{Cases}\index{Cases@{\tt Cases}} + +\marginparwidth 0pt \oddsidemargin 0pt \evensidemargin 0pt \marginparsep 0pt +\topmargin 0pt \textwidth 6.5in \textheight 8.5in + + +\verb+Cases+ is an extension to the concrete syntax of Coq that allows +to write case expressions using patterns in a syntax close to that of ML languages. +This construction is just a macro that is +expanded during parsing into a sequence of the primitive construction + \verb+Case+. +The current implementation contains two strategies, one for compiling +non-dependent case and another one for dependent case. +\section{Patterns}\label{implementation} +A pattern is a term that indicates the {\em shape} of a value, i.e. a +term where the variables can be seen as holes. When a value is +matched against a pattern (this is called {\em pattern matching}) +the pattern behaves as a filter, and associates a sub-term of the value +to each hole (i.e. to each variable pattern). + + +The syntax of patterns is presented in figure \ref{grammar}\footnote{ +Notation: \{$P$\}$^*$ denotes zero or more repetitions of $P$ and + \{$P$\}$^+$ denotes one or more repetitions of $P$. {\sl command} is the +non-terminal corresponding to terms in Coq.}. +Patterns are built up from constructors and variables. Any identifier +that is not a constructor of an inductive or coinductive type is +considered to be +a variable. Identifiers in patterns should be linear except for +the ``don't care'' pattern denoted by ``\verb+_+''. +We can use patterns to build more complex patterns. +We call {\em simple pattern} a variable or a pattern of the form +$(c~\vec{x})$ where $c$ is a constructor symbol and $\vec{x}$ is a +linear vector of variables. If a pattern is +not simple we call it {\em nested}. + + +A variable pattern matches any value, and the +identifier is bound to that value. The pattern ``\verb+_+'' also matches +any value, but it is not binding. Alias patterns written \verb+(+{\sl pattern} \verb+as+ {\sl +identifier}\verb+)+ are also accepted. This pattern matches the same values as +{\sl pattern} does and +{\sl identifier} is bound to the matched value. +A list of patterns is also considered as a pattern and is called {\em +multiple pattern}. + +\begin{figure}[t] +\begin{center} +\begin{sl} +\begin{tabular}{|l|}\hline \\ +\begin{tabular}{rcl}%\hline && \\ +simple\_pattern & := & pattern \verb+as+ identifier \\ + &$|$ & pattern \verb+,+ pattern \\ + &$|$ & pattern pattern\_list \\ && \\ + +pattern & := & identifier $|$ \verb+(+ simple\_pattern \verb+)+ \\ &&\\ + + +equation & := & \{pattern\}$^+$ ~\verb+=>+ ~term \\ && \\ + +ne\_eqn\_list & := & \verb+|+$^{opt}$ equation~ \{\verb+|+ equation\}$^*$ \\ &&\\ + +eqn\_list & := & \{~equation~ \{\verb+|+ equation\}$^*$~\}$^*$\\ &&\\ + + +term & := & +\verb+Cases+ \{term \}$^+$ \verb+of+ ne\_eqn\_list \verb+end+ \\ +&$|$ & \verb+<+term\verb+>+ \verb+Cases+ \{ term \}$^+$ +\verb+of+ eqn\_list \verb+end+ \\&& %\\ \hline +\end{tabular} \\ \hline +\end{tabular} +\end{sl} \end{center} +\caption{Macro Cases syntax.} +\label{grammar} +\end{figure} + + +Pattern matching improves readability. Compare for example the term +of the function {\em is\_zero} of natural +numbers written with patterns and the one written in primitive +concrete syntax (note that the first bar \verb+|+ is optional)~: + +\begin{center} +\begin{small} +\begin{tabular}{l} +\verb+[n:nat] Cases n of | O => true | _ => false end+,\\ +\verb+[n:nat] Case n of true [_:nat]false end+. +\end{tabular} +\end{small} +\end{center} + +In Coq pattern matching is compiled into the primitive constructions, +thus the expressiveness of the theory remains the same. Once the stage +of parsing has finished patterns disappear. An easy way to see the +result of the expansion is by printing the term with \texttt{Print} if +the term is a constant, or +using the command \texttt{Check} that displays +the term with its type : + +\begin{coq_example} +Check [n:nat] Cases n of O => true | _ => false end. +\end{coq_example} + + +\verb+Cases+ accepts optionally an infix term enclosed between +brackets \verb+<>+ that we +call the {\em elimination predicate}. +This term is the same argument as the one expected by the primitive +\verb+Case+. Given a pattern matching +expression, if all the right hand sides of \verb+=>+ ({\em rhs} in +short) have the same type, then this term +can be sometimes synthesized, and so we can omit the \verb+<>+. +Otherwise we have to +provide the predicate between \verb+<>+ as for the primitive \verb+Case+. + +Let us illustrate through examples the different aspects of pattern matching. +Consider for example the function that computes the maximum of two +natural numbers. We can write it in primitive syntax by: +\begin{coq_example} +Fixpoint max [n,m:nat] : nat := + Case n of + (* O *) m + (* S n' *) [n':nat]Case m of + (* O *) (S n') + (* S m' *) [m':nat](S (max n' m')) + end + end. +\end{coq_example} + +Using patterns in the definitions gives: + +\begin{coq_example} +Reset max. +Fixpoint max [n,m:nat] : nat := + Cases n of + O => m + | (S n') => Cases m of + O => (S n') + | (S m') => (S (max n' m')) + end + end. +\end{coq_example} + +Another way to write this definition is to use a multiple pattern to + match \verb+n+ and \verb+m+: + +\begin{coq_example} +Reset max. +Fixpoint max [n,m:nat] : nat := + Cases n m of + O _ => m + | (S n') O => (S n') + | (S n') (S m') => (S (max n' m')) + end. +\end{coq_example} + + +The strategy examines patterns +from left to right. A case expression is generated {\bf only} when there is at least one constructor in the column of patterns. +For example, +\begin{coq_example} +Check [x:nat]<nat>Cases x of y => y end. +\end{coq_example} + + + +We can also use ``\verb+as+ patterns'' to associate a name to a +sub-pattern: + +\begin{coq_example} +Reset max. +Fixpoint max [n:nat] : nat -> nat := + [m:nat] Cases n m of + O _ => m + | ((S n') as N) O => N + | (S n') (S m') => (S (max n' m')) + end. +\end{coq_example} + + +In the previous examples patterns do not conflict with, but +sometimes it is comfortable to write patterns that admits a non +trivial superposition. Consider +the boolean function $lef$ that given two natural numbers +yields \verb+true+ if the first one is less or equal than the second +one and \verb+false+ otherwise. We can write it as follows: + +\begin{coq_example} +Fixpoint lef [n,m:nat] : bool := + Cases n m of + O x => true + | x O => false + | (S n) (S m) => (lef n m) + end. +\end{coq_example} + +Note that the first and the second multiple pattern superpose because the couple of +values \verb+O O+ matches both. Thus, what is the result of the +function on those values? +To eliminate ambiguity we use the {\em textual priority rule}: we +consider patterns ordered from top to bottom, then a value is matched +by the pattern at the $ith$ row if and only if is not matched by some +pattern of a previous row. Thus in the example, +\verb+O O+ is matched by the first pattern, and so \verb+(lef O O)+ +yields \verb+true+. + +Another way to write this function is: + +\begin{coq_example} +Reset lef. +Fixpoint lef [n,m:nat] : bool := + Cases n m of + O x => true + | (S n) (S m) => (lef n m) + | _ _ => false + end. +\end{coq_example} + + +Here the last pattern superposes with the first two. Because +of the priority rule, the last pattern +will be used only for values that do not match neither the first nor +the second one. + +Terms with useless patterns are accepted by the +system. For example, +\begin{coq_example} +Check [x:nat]Cases x of O => true | (S _) => false | x => true end. +\end{coq_example} + +is accepted even though the last pattern is never used. +Beware, the +current implementation rises no warning message when there are unused +patterns in a term. + + + + +\subsection{About patterns of parametric types} +When matching objects of a parametric type, constructors in patterns +{\em do not expect} the parameter arguments. Their value is deduced +during expansion. + +Consider for example the polymorphic lists: + +\begin{coq_example} +Inductive List [A:Set] :Set := + nil:(List A) +| cons:A->(List A)->(List A). +\end{coq_example} + +We can check the function {\em tail}: + +\begin{coq_example} +Check [l:(List nat)]Cases l of + nil => (nil nat) + | (cons _ l') => l' + end. +\end{coq_example} + + +When we use parameters in patterns there is an error message: +\begin{coq_example} +Check [l:(List nat)]Cases l of + (nil nat) => (nil nat) + | (cons nat _ l') => l' + end. +\end{coq_example} + + + +\subsection{Matching objects of dependent types} +The previous examples illustrate pattern matching on objects of +non-dependent types, but we can also +use the macro to destructure objects of dependent type. +Consider the type \verb+listn+ of lists of a certain length: + +\begin{coq_example} +Inductive listn : nat-> Set := + niln : (listn O) +| consn : (n:nat)nat->(listn n) -> (listn (S n)). +\end{coq_example} + +\subsubsection{Understanding dependencies in patterns} +We can define the function \verb+length+ over \verb+listn+ by : + +\begin{coq_example} +Definition length := [n:nat][l:(listn n)] n. +\end{coq_example} + +Just for illustrating pattern matching, +we can define it by case analysis: +\begin{coq_example} +Reset length. +Definition length := [n:nat][l:(listn n)] + Cases l of + niln => O + | (consn n _ _) => (S n) + end. +\end{coq_example} + +We can understand the meaning of this definition using the +same notions of usual pattern matching. + +Now suppose we split the second pattern of \verb+length+ into two +cases so to give an +alternative definition using nested patterns: +\begin{coq_example} +Definition length1:= [n:nat] [l:(listn n)] + Cases l of + niln => O + | (consn n _ niln) => (S n) + | (consn n _ (consn _ _ _)) => (S n) + end. +\end{coq_example} + +It is obvious that \verb+length1+ is another version of +\verb+length+. We can also give the following definition: +\begin{coq_example} +Definition length2:= [n:nat] [l:(listn n)] + Cases l of + niln => O + | (consn n _ niln) => (S O) + | (consn n _ (consn m _ _)) => (S (S m)) + end. +\end{coq_example} + +If we forget that \verb+listn+ is a dependent type and we read these +definitions using the usual semantics of pattern matching, we can conclude +that \verb+length1+ +and \verb+length2+ are different functions. +In fact, they are equivalent +because the pattern \verb+niln+ implies that \verb+n+ can only match +the value $0$ and analogously the pattern \verb+consn+ determines that \verb+n+ can +only match values of the form $(S~v)$ where $v$ is the value matched by +\verb+m+. + + +The converse is also true. If +we destructure the length value with the pattern \verb+O+ then the list +value should be $niln$. +Thus, the following term \verb+length3+ corresponds to the function +\verb+length+ but this time defined by case analysis on the dependencies instead of on the list: + +\begin{coq_example} +Definition length3 := [n:nat] [l: (listn n)] + Cases l of + niln => O + | (consn O _ _) => (S O) + | (consn (S n) _ _) => (S (S n)) + end. +\end{coq_example} + +When we have nested patterns of dependent types, the semantics of +pattern matching becomes a little more difficult because +the set of values that are matched by a sub-pattern may be conditioned by the +values matched by another sub-pattern. Dependent nested patterns are +somehow constrained patterns. +In the examples, the expansion of +\verb+length1+ and \verb+length2+ yields exactly the same term + but the +expansion of \verb+length3+ is completely different. \verb+length1+ and +\verb+length2+ are expanded into two nested case analysis on +\verb+listn+ while \verb+length3+ is expanded into a case analysis on +\verb+listn+ containing a case analysis on natural numbers inside. + + +In practice the user can think about the patterns as independent and +it is the expansion algorithm that cares to relate them. \\ + + +\subsubsection{When the elimination predicate must be provided} +The examples given so far do not need an explicit elimination predicate +between \verb+<>+ because all the rhs have the same type and the +strategy succeeds to synthesize it. +Unfortunately when dealing with dependent patterns it often happens +that we need to write cases where the type of the rhs are +different instances of the elimination predicate. +The function \verb+concat+ for \verb+listn+ +is an example where the branches have different type +and we need to provide the elimination predicate: + +\begin{coq_example} +Fixpoint concat [n:nat; l:(listn n)] :(m:nat) (listn m) -> (listn (plus n m)) + := [m:nat][l':(listn m)] + <[n:nat](listn (plus n m))>Cases l of + niln => l' + | (consn n' a y) => (consn (plus n' m) a (concat n' y m l')) + end. +\end{coq_example} + +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 type we need to provide +the elimination predicate for this multiple pattern. + +For example, an equivalent definition for \verb+concat+ (even though with a useless extra pattern) would have +been: + +\begin{coq_example} +Reset concat. +Fixpoint concat [n:nat; l:(listn n)] : (m:nat) (listn m) -> (listn (plus n m)) +:= [m:nat][l':(listn m)] + <[n,_:nat](listn (plus n m))>Cases l l' of + niln x => x + | (consn n' a y) x => (consn (plus n' m) a (concat n' y m x)) + end. +\end{coq_example} + +Note that this time, the predicate \verb+[n,_:nat](listn (plus n m))+ is binary because we +destructure both \verb+l+ and \verb+l'+ whose types have arity one. +In general, if we destructure the terms $e_1\ldots e_n$ +the predicate will be of arity $m$ where $m$ is the sum of the +number of dependencies of the type of $e_1, e_2,\ldots e_n$ (the $\lambda$-abstractions +should correspond from left to right to each dependent argument of the +type of $e_1\ldots e_n$). +When the arity of the predicate (i.e. number of abstractions) is not +correct Coq rises an error message. For example: + +\begin{coq_example} +Fixpoint concat [n:nat; l:(listn n)] : (m:nat) (listn m) -> (listn (plus n m)) := +[m:nat][l':(listn m)] + <[n:nat](listn (plus n m))>Cases l l' of + niln x => x + | (consn n' a y) x => (consn (plus n' m) a (concat n' y m x)) + end. +\end{coq_example} + + +\subsection{Using pattern matching to write proofs} +In all the previous examples the elimination predicate does not depend on the object(s) matched. +The typical case where this is not possible is when we write a proof by +induction or a function that yields an object of dependent type. + +For example, we can write +the function \verb+buildlist+ that given a natural number +$n$ builds a list length $n$ containing zeros as follows: + +\begin{coq_example} +Fixpoint buildlist [n:nat] : (listn n) := + <[n:nat](listn n)>Cases n of + O => niln + | (S n) => (consn n O (buildlist n)) + end. +\end{coq_example} + +We can also use multiple patterns whenever the elimination predicate has +the correct arity. + +Consider the following definition of the predicate less-equal +\verb+Le+: + +\begin{coq_example} +Inductive Le : nat->nat->Prop := + LeO: (n:nat)(Le O n) +| LeS: (n,m:nat)(Le n m) -> (Le (S n) (S m)). +\end{coq_example} + +We can use multiple patterns to write the proof of the lemma + \verb+(n,m:nat) (Le n m)\/(Le m n)+: + +\begin{coq_example} +Fixpoint dec [n:nat] : (m:nat)(Le n m) \/ (Le m n) := + [m:nat] <[n,m:nat](Le n m) \/ (Le m n)>Cases n m of + O x => (or_introl ? (Le x O) (LeO x)) + | x O => (or_intror (Le x O) ? (LeO x)) + | ((S n) as N) ((S m) as M) => + Cases (dec n m) of + (or_introl h) => (or_introl ? (Le M N) (LeS n m h)) + | (or_intror h) => (or_intror (Le N M) ? (LeS m n h)) + end + end. +\end{coq_example} +In the example of \verb+dec+ the elimination predicate is binary +because we destructure two arguments of \verb+nat+ that is a +non-dependent type. Note the first \verb+Cases+ is dependent while the +second is not. + +In general, consider the terms $e_1\ldots e_n$, +where the type of $e_i$ is an instance of a family type +$[\vec{d_i}:\vec{D_i}]T_i$ ($1\leq i +\leq n$). Then to write \verb+<+${\cal P}$\verb+>Cases+ $e_1\ldots +e_n$ \verb+of+ \ldots \verb+end+, the +elimination predicate ${\cal P}$ should be of the form: +$[\vec{d_1}:\vec{D_1}][x_1:T_1]\ldots [\vec{d_n}:\vec{D_n}][x_n:T_n]Q.$ + + + + +\section{Extending the syntax of pattern} +The primitive syntax for patterns considers only those patterns containing +symbols of constructors and variables. Nevertheless, we +may define our own syntax for constructors and may be interested in +using this syntax to write patterns. +Because not any term is a pattern, the fact of extending the terms +syntax does not imply the extension of pattern syntax. Thus, +the grammar of patterns should be explicitly extended whenever we +want to use a particular syntax for a constructor. +The grammar rules for the macro \verb+Cases+ (and thus for patterns) +are defined in the file \verb+Multcase.v+ in the directory +\verb+src/syntax+. To extend the grammar of patterns +we need to extend the non-terminals corresponding to patterns +(we refer the reader to chapter of grammar extensions). + + +We have already extended the pattern syntax so as to note +the constructor \verb+pair+ of cartesian product with "( , )" in patterns. +This allows for example, to write the first projection +of pairs as follows: +\begin{coq_example} +Definition fst := [A,B:Set][H:A*B] Cases H of (x,y) => x end. +\end{coq_example} +The grammar presented in figure \ref{grammar} actually +contains this extension. + +\section{When does the expansion strategy fail?}\label{limitations} +The strategy works very like in ML languages when treating +patterns of non-dependent type. +But there are new cases of failure that are due to the presence of +dependencies. + +The error messages of the current implementation may be +sometimes confusing. +When the tactic fails because patterns are somehow incorrect then +error messages refer to the initial expression. But the strategy +may succeed to build an expression whose sub-expressions are well typed but +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 {\small\verb+(cons n O x) => e1+} and {\small\verb+(cons n \_ x) => e2+} instead of +{\small\verb+(cons n O x) => e1+} and {\small\verb+(cons n' \_ x') => e2+}. This helps to maintain certain name correspondence between the generated expression and the original. + + +Here is a summary of the error messages corresponding to each situation: +\begin{itemize} +\item patterns are incorrect (because constructors are not +applied to the correct number of the arguments, because they are not linear or they are +wrongly typed) +\begin{itemize} +\item \sverb{In pattern } {\sl term} \sverb{the constructor } {\sl ident} +\sverb{expects } {\sl num} \sverb{arguments} + +\item \sverb{The variable } {\sl ident} \sverb{is bound several times in pattern } {\sl term} + +\item \sverb{Constructor pattern: } {\sl term} \sverb{cannot match values of type } {\sl term} +\end{itemize} + +\item the pattern matching is not exhaustive +\begin{itemize} +\item \sverb{This pattern-matching is not exhaustive} +\end{itemize} +\item the elimination predicate provided to \verb+Cases+ has not the expected arity + +\begin{itemize} +\item \sverb{The elimination predicate } {\sl term} \sverb{should be +of arity } {\sl num} \sverb{(for non dependent case) or } {\sl num} \sverb{(for dependent case)} +\end{itemize} + + \item the whole expression is wrongly typed, or the synthesis of implicit arguments fails (for example to find +the elimination predicate or to resolve implicit arguments in the rhs). + + +There are {\em nested patterns of dependent type}, the +elimination predicate corresponds to non-dependent case and has the form $[x_1:T_1]...[x_n:T_n]T$ +and {\bf some} $x_i$ occurs {\bf free} in +$T$. Then, the strategy may fail to find out a correct elimination +predicate during some step of compilation. +In this situation we recommend the user to rewrite the nested +dependent patterns into several \verb+Cases+ with {\em simple patterns}. + +In all these cases we have the following error message: + + \begin{itemize} + \item + {\tt Expansion strategy failed to build a well typed case expression. + There is a branch that mismatches the expected type. + The risen type error on the result of expansion was:} + \end{itemize} + +\item because of nested patterns, it may happen that even though all +the rhs have the same type, the strategy needs +dependent elimination and so an elimination predicate must be +provided. The system +warns about this situation, trying to compile anyway with the +non-dependent strategy. The risen message is: +\begin{itemize} +\item {\tt Warning: This pattern matching may need dependent elimination to be compiled. +I will try, but if fails try again giving dependent elimination predicate.} +\end{itemize} + +\item there are {\em nested patterns of dependent type} and the strategy +builds a term that is well typed but recursive +calls in fix point are reported as illegal: +\begin{itemize} +\item {\tt Error: Recursive call applied to an illegal term ...} +\end{itemize} + +This is because the strategy generates a term that is correct +w.r.t. to the initial term but which does not pass the guard condition. +In this situation we recommend the user to transform the nested dependent +patterns into {\em several \verb+Cases+ of simple patterns}. +Let us explain this with an example. +Consider the following defintion of a function that yields the last +element of a list and \verb+O+ if it is empty: + +\begin{coq_example} +Fixpoint last [n:nat; l:(listn n)] : nat := +Cases l of + (consn _ a niln) => a + | (consn m _ x) => (last m x) + | niln => O + end. +\end{coq_example} + +It fails because of the priority between patterns, we know that this +definition is equivalent to the following more explicit one (which +fails too): + +\begin{coq_example*} +Fixpoint last [n:nat; l:(listn n)] : nat := +Cases l of + (consn _ a niln) => a + | (consn n _ (consn m b x)) => (last n (consn m b x)) + | niln => O + end. +\end{coq_example*} + +Note that the recursive call \sverb{(last n (consn m b x)) } is not +guarded. When treating with patterns of dependent types the strategy +interprets the first definition of \texttt{last} as the second +onefootnote{In languages of the ML family +the first definition would be translated into a term where the +variable \texttt{x} is shared in the expression. When +patterns are of non-dependent types, Coq compiles as in ML languages +using sharing. When patterns are of dependent types the compilation +reconstructs the term as in the second definition of \texttt{last} so to +ensure the result of expansion is well typed.}. +Thus it generates a +term where the recursive call is rejected by the +guard condition. + +You can get rid of this problem by writing the definition with \emph{simple +patterns}: + +\begin{coq_example} +Fixpoint last [n:nat; l:(listn n)] : nat := +<[_:nat]nat>Cases l of + (consn m a x) => Cases x of + niln => a + | _ => (last m x) + end + | niln => O + end. +\end{coq_example} + + +\end{itemize} + +%\end{document} + diff --git a/doc/RefMan-cic.tex b/doc/RefMan-cic.tex new file mode 100755 index 000000000..51bbc506a --- /dev/null +++ b/doc/RefMan-cic.tex @@ -0,0 +1,1233 @@ +\chapter{The Calculus of Inductive Constructions} +\label{Cic} +\index{Cic@\textsc{CIC}} +\index{Calculus of (Co)Inductive Constructions} + +The underlying formal language of {\Coq} is the {\em Calculus of +(Co)Inductive Constructions}\index{Calculus of (Co)Inductive Constructions} +(\CIC\ in short). It is presented in this chapter. + +In \CIC\, all objects have a {\em 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, the statement {\it ``for all x, P''} is not +allowed in type theory; you must say instead: {\it ``for all x +belonging to T, P''}. The expression {\it ``x belonging to T''} is +written {\it ``x:T''}. One also says: {\it ``x has type T''}. +The terms of {\CIC} are detailed in section \ref{Terms}. + +In \CIC\, there is an internal reduction mechanism. In particular, it +allows to decide if two programs are {\em intentionally} equal (one +says {\em convertible}). Convertibility is presented in section +\ref{convertibility}. + +The remaining sections are concerned with the type-checking of terms. +The beginner can skip them. + +The reader seeking a background on the {\CIC} may read several +papers. Giménez~\cite{Gim98} +provides an introduction to inductive and coinductive +definitions in Coq, Werner~\cite{Wer94} and Paulin-Mohring~\cite{Moh97} are the +most recent theses on the +{\CIC}. Coquand-Huet~\cite{CoHu85a,CoHu85b,CoHu86} introduces the +Calculus of Constructions. Coquand-Paulin~\cite{CoPa89} introduces +inductive definitions. The {\CIC} is a formulation of type theory +including the possibility of inductive +constructions. Barendregt~\cite{Bar91} studies the modern form of type +theory. + +\section{The terms}\label{Terms} + +In most type theories, one usually makes a syntactic distinction +between types and terms. This is not the case for \CIC\ which defines +both types and terms in the same syntactical structure. This is +because the type-theory itself forces terms and types to be defined in +a mutual recursive way and also because similar constructions can be +applied to both terms and types and consequently can share the same +syntactic structure. + +For instance the type of functions will have several meanings. Assume +\nat\ is the type of natural numbers then $\nat\ra\nat$ is the type of +functions from \nat\ to \nat, $\nat \ra \Prop$ is the type of unary +predicates over the natural numbers. For instance $[x:\nat](x=x)$ will +represent a predicate $P$, informally written in mathematics +$P(x)\equiv x=x$. If $P$ has type $\nat \ra \Prop$, $(P~x)$ is a +proposition, furthermore $(x:\nat)(P~x)$ will represent the type of +functions which associate to each natural number $n$ an object of +type $(P~n)$ and consequently represent proofs of the formula +``$\forall x.P(x)$''. + +\subsection{Sorts}\label{Sorts} +\index{Sorts} +Types are seen as terms of the language and then should belong to +another type. The type of a type is always a constant of the language +called a sort. + +The two basic sorts in the language of \CIC\ are \Set\ and \Prop. + +The sort \Prop\ intends to be the type of logical propositions. If +$M$ is a logical proposition then it denotes a class, namely the class +of terms representing proofs of $M$. An object $m$ belonging to $M$ +witnesses the fact that $M$ is true. An object of type \Prop\ is +called a {\em proposition}. + +The sort \Set\ intends to be the type of specifications. This includes +programs and the usual sets such as booleans, naturals, lists +etc. + +These sorts themselves can be manipulated as ordinary terms. +Consequently sorts also should be given a type. Because assuming +simply that \Set\ has type \Set\ leads to an inconsistent theory, we +have infinitely many sorts in the language of \CIC\ . These are, in +addition to \Set\ and \Prop\, a hierarchy of universes \Type$(i)$ +for any integer $i$. We call \Sort\ the set of sorts +which is defined by: +\[\Sort \equiv \{\Prop,\Set,\Type(i)| i \in \NN\} \] +\index{Type@{\Type}} +\index{Prop@{\Prop}} +\index{Set@{\Set}} +The sorts enjoy the following properties: {\Prop:\Type(0)} and + {\Type$(i)$:\Type$(i+1)$}. + +The user will never mention explicitly the index $i$ when referring to +the universe \Type$(i)$. One only writes \Type. The +system itself generates for each instance of \Type\ a new +index for the universe and checks that the constraints between these +indexes can be solved. From the user point of view we consequently +have {\sf Type :Type}. + +We shall make precise in the typing rules the constraints between the +indexes. + +\medskip +\Rem +The extraction mechanism is not compatible with this universe +hierarchy. It is supposed to work only on terms which are explicitly +typed in the Calculus of Constructions without universes and with +Inductive Definitions at the Set level and only a small elimination. +In other cases, extraction may generate a dummy answer and sometimes +failed. To avoid failure when developing proofs, an error while +extracting the computational contents of a proof will not stop the +proof but only give a warning. + + +\subsection{Constants} +Besides the sorts, the language also contains constants denoting +objects in the environment. These constants may denote previously +defined objects but also objects related to inductive definitions +(either the type itself or one of its constructors or destructors). + +\medskip\noindent {\bf Remark. } In other presentations of \CIC, +the inductive objects are not seen as +external declarations but as first-class terms. Usually the +definitions are also completely ignored. This is a nice theoretical +point of view but not so practical. An inductive definition is +specified by a possibly huge set of declarations, clearly we want to +share this specification among the various inductive objects and not +to duplicate it. So the specification should exist somewhere and the +various objects should refer to it. We choose one more level of +indirection where the objects are just represented as constants and +the environment gives the information on the kind of object the +constant refers to. + +\medskip +Our inductive objects will be manipulated as constants declared in the +environment. This roughly corresponds to the way they are actually +implemented in the \Coq\ system. It is simple to map this presentation +in a theory where inductive objects are represented by terms. + +\subsection{Language} + +\paragraph{Types.} + +Roughly speaking types can be separated into atomic and composed +types. + +An atomic type of the {\em Calculus of Inductive Constructions} is +either a sort or is built from a type variable or an inductive +definition applied to some terms. + +A composed type will be a product $(x:T)U$ with $T$ and $U$ two types. + +\paragraph{Terms.} +A term is either a type or a term variable or a term constant of the +environment. + +As usual in $\lambda$-calculus, we combine objects using abstraction +and application. + +More precisely the language of the {\em Calculus of Inductive + Constructions} is built with the following rules: + +\begin{enumerate} +\item the sorts {\sf Set, Prop, Type} are terms. +\item constants of the environment are terms. +\item variables are terms. +\item if $x$ is a variable and $T$, $U$ are terms then $(x:T)U$ is a + term. If $x$ occurs in $U$, $(x:T)U$ reads as {\it ``for all x of + type T, U''}. As $U$ depends on $x$, one says that $(x:T)U$ is a + {\em dependent product}. If $x$ doesn't occurs in $U$ then $(x:T)U$ + reads as {\it ``if T then U''}. A non dependent product can be + written: $T \rightarrow U$. +\item if $x$ is a variable and $T$, $U$ are terms then $[x:T]U$ is a + term. This is a notation for the $\lambda$-abstraction of + $\lambda$-calculus\index{lambda-calculus@$\lambda$-calculus} + \cite{Bar81}. The term $[x:T]U$ is a function which maps elements of + $T$ to $U$. +\item if $T$ and $U$ are terms then $(T\ U)$ is a term. The term $(T\ + U)$ reads as {\it ``T applied to U''}. +\end{enumerate} + +\paragraph{Notations.} Application associates to the left such that +$(t~t_1\ldots t_n)$ represents $(\ldots (t~t_1)\ldots t_n)$. The +products and arrows associate to the right such that $(x:A)B\ra C\ra +D$ represents $(x:A)(B\ra (C\ra D))$. One uses sometimes $(x,y:A)B$ or +$[x,y:A]B$ to denote the abstraction or product of several variables +of the same type. The equivalent formulation is $(x:A)(y:A)B$ or +$[x:A][y:A]B$ +\paragraph{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. They +are represented by de Bruijn indexes in the internal structure of +terms. + +\paragraph{Substitution.} \index{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 +will be written $\subst{U}{x}{T}$. + + +\section{Typed terms}\label{Typed-terms} +As objects of type theory, terms are subjected to {\em type + discipline}. The well typing of a term depends on a set of +declarations of variables we call a {\em context}. A context $\Gamma$ +is written $[x_1:T_1;..; x_n:T_n]$ where the $x_i$'s are distinct +variables and the $T_i$'s are terms. If $\Gamma$ contains some $x:T$, +we write $(x:T)\in\Gamma$ and also $x \in\Gamma$. Contexts must be +themselves {\em well formed}. The notation $\Gamma::(y:T)$ denotes +the context $[x_1:T_1;..;x_n:T_n;y:T]$. The notation $[]$ denotes the +empty context. +\index{Context} + +We define the inclusion of two contexts $\Gamma$ and $\Delta$ (written +as $\Gamma \subset \Delta$) as the property, for all variable $x$ and +type $T$, if $(x:T) \in \Gamma$ then $(x:T)\in \Delta$. We write +$|\Delta|$ for the length of the context $\Delta$ which is $n$ if +$\Delta$ is $[x_1:T_1;..; x_n:T_n]$. + +A variable $x$ is said to be free in $\Gamma$ if $\Gamma$ contains a +declaration $y:T$ such that $x$ is free in $T$. + +\paragraph{Environment.}\index{Environment} +Because we are manipulating constants, we also need to consider an +environment $E$. We shall give afterwards the rules for introducing +new objects in the environment. For the typing relation of terms, it +is enough to introduce two notions. One which says if a name is +defined in the environment we shall write $c \in E$ and the other one +which gives the type of this constant in $E$. We shall write $(c : T) +\in E$. + +In the following, we assume $E$ is a valid environment. We define +simultaneously two judgments. The first one \WTEG{t}{T} means the +term $t$ is well-typed and has type $T$ in the environment $E$ and +context $\Gamma$. The second judgment \WFE{\Gamma} means that the +environment $E$ is well-formed and the context $\Gamma$ is a valid +context in this environment. It also means a third property which +makes sure that any constant in $E$ was defined in an environment +which is included in $\Gamma$ +\footnote{This requirement could be relaxed if we instead introduced + an explicit mechanism for instantiating constants. At the external + level, the Coq engine works accordingly to this view that all the + definitions in the environment were built in a sub-context of the + current context.}. + +A term $t$ is well typed in an environment $E$ iff there exists a +context $\Gamma$ and a term $T$ such that the judgment \WTEG{t}{T} can +be derived from the following rules. +\begin{itemize}\label{Typing-rules}\index{Typing rules} +\item [W-E] \inference{\WF{[]}{[]}} +\item [W-$s$] +\inference{\frac{\WTEG{T}{s}~~~~s\in \Sort~~~~x \not\in + \Gamma \cup E}{\WFE{\Gamma::(x:T)}}} +\item [Ax] \index{Typing rules!Ax} +\inference{\frac{\WFE{\Gamma}}{\WTEG{\Prop}{\Type(p)}}~~~~~ +\frac{\WFE{\Gamma}}{\WTEG{\Set}{\Type(q)}}}\\[3mm] +\inference{\frac{\WFE{\Gamma}~~~~i<j}{\WTEG{\Type(i)}{\Type(j)}}} +\item[Var]\index{Typing rules!Var} + \inference{\frac{ \WFE{\Gamma}~~~~~(x:T)\in\Gamma}{\WTEG{x}{T}}} +\item[Const] \index{Typing rules!Const} +\inference{\frac{\WFE{\Gamma}~~~~(c:T) \in E}{\WTEG{c}{T}}} +\item [Prod] \index{Typing rules!Prod} +\inference{\frac{\WTEG{T}{s_1}~~~~ + \WTE{\Gamma::(x:T)}{U}{s_2}~~~s_1\in\{\Prop, \Set\}~\mbox{or}~ + s_2\in\{\Prop, \Set\}} + { \WTEG{(x:T)U}{s_2}}} \\[3mm] +\inference{\frac{\WTEG{T}{\Type(i)}~~~~ + \WTE{\Gamma::(x:T)}{U}{\Type(j)}~~~i\leq + k~~~j \leq k}{ \WTEG{(x:T)U}{\Type(k)}}} +\item [Lam]\index{Typing rules!Lam} +\inference{\frac{\WTEG{(x:T)U}{s}~~~~ \WTE{\Gamma::(x:T)}{t}{U}} + {\WTEG{[x:T]t}{(x:T)U}}} +\item [App]\index{Typing rules!App} + \inference{\frac{\WTEG{t}{(x:U)T}~~~~\WTEG{u}{U}} + {\WTEG{(t\ u)}{\subst{T}{x}{u}}}} +\end{itemize} + +\section{Conversion rules} +\index{Conversion rules} +\label{conv-rules} +\paragraph{$\beta$-reduction.} +\label{beta}\index{beta-reduction@$\beta$-reduction} + +We want to be able to identify some terms as we can identify the +application of a function to a given argument with its result. For +instance the identity function over a given type $T$ can be written +$[x:T]x$. We want to identify any object $a$ (of type $T$) with the +application $([x:T]x~a)$. We define for this a {\em reduction} (or a +{\em conversion}) rule we call $\beta$: +\[ ([x:T]t~u) \triangleright_{\beta} \subst{t}{x}{u} \] + +We say that $\subst{t}{x}{u}$ is the {\em $\beta$-contraction} of +$([x:T]t~u)$ and, conversely, that $([x:T]t~u)$ is the {\em + $\beta$-expansion} of $\subst{t}{x}{u}$. + +According to $\beta$-reduction, terms of the {\em Calculus of + Inductive Constructions} enjoy some fundamental properties such as +confluence, strong normalization, subject reduction. These results are +theoretically of great importance but we will not detail them here and +refer the interested reader to \cite{Coq85}. + +\paragraph{$\iota$-reduction.} +\label{iota}\index{iota-reduction@$\iota$-reduction} +A specific conversion rule is associated to the inductive objects in +the environment. We shall give later on (section \ref{iotared}) the +precise rules but it just says that a destructor applied to an object +built from a constructor behaves as expected. This reduction is +called $\iota$-reduction and is more precisely studied in +\cite{Moh93,Wer94}. + + +\paragraph{$\delta$-reduction.} +\label{convertibility} +\label{delta}\index{delta-reduction@$\delta$-reduction} +In the environment we also have constants representing abbreviations +for terms. It is legal to identify a constant with its value. This +reduction will be precised in section \ref{deltared} where we define +well-formed environments. This reduction will be called +$\delta$-reduction. + +\paragraph{Convertibility.} +\index{beta-conversion@$\beta$-conversion}\index{iota-conversion@$\iota$-conversion}\index{delta-conversion@$\delta$-conversion} + + +Let us write $t \triangleright u$ for the relation $t$ reduces to $u$ +with one of the previous reduction $\beta,\iota$ or $\delta$. + +We say that two terms $t_1$ and $t_2$ are {\em convertible} (or {\em + equivalent)} iff there exists a term $u$ such that $t_1 +\triangleright \ldots \triangleright u$ and $t_2 \triangleright \ldots +\triangleright u$. We note $t_1 \convert t_2$. + +The convertibility relation allows to introduce a new typing rule +which says that two convertible well-formed types have the same +inhabitants. + +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 property is included into the +conversion rule by extending the equivalence relation of +convertibility into an order inductively defined by: +\begin{enumerate} +\item if $M\convert N$ then $M\leconvert N$, +\item if $i \leq j$ then $\Type(i)\leconvert\Type(j)$, +\item if $T \convert U$ and $M\leconvert N$ then $(x:T)M\leconvert + (x:U)N$. +\end{enumerate} + +The conversion rule is now exactly: + +\begin{itemize}\label{Conv} +\item [Conv]\index{Typing rules!Conv} + \inference{ + \frac{\WTEG{U}{S}~~~~\WTEG{t}{T}~~~~T \leconvert U}{\WTEG{t}{U}}} +\end{itemize} + + +\paragraph{$\eta$-conversion.}\label{eta}\index{eta-conversion@$\eta$-conversion}\index{eta-reduction@$\eta$-reduction} +An other important rule is the $\eta$-conversion. It is to identify +terms over a dummy abstraction of a variable followed by an +application of this variable. Let $T$ be a type, $t$ be a term in +which the variable $x$ doesn't occurs free. We have +\[ [x:T](t\ x) \triangleright t \] +Indeed, as $x$ doesn't occurs free in $t$, for any $u$ one +applies to $[x:T](t\ x)$, it $\beta$-reduces to $(t\ u)$. So +$[x:T](t\ x)$ and $t$ can be identified. + +\Rem The $\eta$-reduction is not taken into account in the +convertibility rule of \Coq. + +\paragraph{Normal form.}\index{Normal form}\label{Normal-form}\label{Head-normal-form}\index{Head normal form} +A term which cannot be any more reduced is said to be in {\em normal + form}. There are several ways (or strategies) to apply the reduction +rule. Among them, we have to mention the {\em head reduction} which +will play an important role (see chapter \ref{Tactics}). Any term can +be written as $[x_1:T_1]\ldots[x_k:T_k](t_0\ t_1\ldots t_n)$ where +$t_0$ is not an application. We say then that $t_0$ is the {\em head + of $t$}. If we assume that $t_0$ is $[x:T]u_0$ then one step of +$\beta$-head reduction of $t$ is: +\[[x_1:T_1]\ldots[x_k:T_k]([x:T]u_0\ t_1\ldots t_n) +~\triangleright ~ [x_1:T_1]\ldots[x_k:T_k](\subst{u_0}{x}{t_1}\ t_2 \ldots t_n)\] +Iterating the process of head reduction until the head of the reduced +term is no more an abstraction leads to the {\em $\beta$-head normal + form} of $t$: +\[ t \triangleright \ldots \triangleright [x_1:T_1]\ldots[x_k:T_k](v\ u_1 +\ldots u_m)\] +where $v$ is not an abstraction (nor an application). Note that the +head normal form must not be confused with the normal form since some +$u_i$ can be reducible. + +Similar notions of head-normal forms involving $\delta$ and $\iota$ +reductions or any combination of those can also be defined. + +\section{Definitions in environments}\label{Cic-definitions} +We now give the rules for manipulating objects in the environment. +Because a constant can depend on previously introduced constants, the +environment will be an ordered list of declarations. When specifying +an inductive definition, several objects will be introduced at the +same time. So any object in the environment will define one or more +constants. + +In this presentation we introduce two different sorts of objects in +the environment. The first one is ordinary definitions which give a +name to a particular well-formed term, the second one is inductive +definitions which introduce new inductive objects. + +\subsection{Rules for definitions} + +\paragraph{Adding a new definition.} +The simplest objects in the environment are definitions which can be +seen as one possible mechanism for abbreviation. + +A definition will be represented in the environment as +\Def{\Gamma}{c}{t}{T} which means that $c$ is a constant which is +valid in the context $\Gamma$ whose value is $t$ and type is $T$. + +\paragraph{$\delta$-reduction.} \label{deltared} +If \Def{\Gamma}{c}{t}{T} is in the environment $E$ then in this +environment the $\delta$-reduc\-tion $c \triangleright_{\delta} t$ is +introduced. + +The rule for adding a new definition is simple: + +\begin{description} +\item[Def] \inference{\frac{\WTEG{t}{T}~~~c \notin E\cup \Gamma} + {\WF{E;\Def{\Gamma}{c}{t}{T}}{\Gamma}}} +\end{description} + +\subsection{Derived rules} + +From the original rules of the type system, one can derive new rules +which change the context of definition of objects in the environment. +Because these rules correspond to elementary operations in the \Coq\ +engine used in the discharge mechanism at the end of a section, we +state them explicitly. + +\paragraph{Mechanism of substitution.} + +One rule which can be proved valid, is to replace a term $c$ by its +value in the environment. As we defined the substitution of a term for +a variable in a term, one can define the substitution of a term for a +constant. One easily extends this substitution to contexts and +environments. + +\paragraph{Substitution Property:} +\inference{\frac{\WF{E;\Def{\Gamma}{c}{t}{T}; F}{\Delta}} + {\WF{E; \subst{F}{c}{t}}{\subst{\Delta}{c}{t}}}} + + +\paragraph{Abstraction.} + +One can modify the context of definition of a constant $c$ by +abstracting a constant with respect to the last variable $x$ of its +defining context. For doing that, we need to check that the constants +appearing in the body of the declaration do not depend on $x$, we need +also to modify the reference to the constant $c$ in the environment +and context by explicitly applying this constant to the variable $x$. +Because of the rules for building environments and terms we know the +variable $x$ is available at each stage where $c$ is mentioned. + +\paragraph{Abstracting property:} + \inference{\frac{\WF{E; \Def{\Gamma::(x:U)}{c}{t}{T}; + F}{\Delta}~~~~\WFE{\Gamma}} + {\WF{E;\Def{\Gamma}{c}{[x:U]t}{(x:U)T}; + \subst{F}{c}{(c~x)}}{\subst{\Delta}{c}{(c~x)}}}} + +\paragraph{Pruning the context.} +We said the judgment \WFE{\Gamma} means that the defining contexts of +constants in $E$ are included in $\Gamma$. If one abstracts or +substitutes the constants with the above rules then it may happen +that the context $\Gamma$ is now bigger than the one needed for +defining the constants in $E$. Because defining contexts are growing +in $E$, the minimum context needed for defining the constants in $E$ +is the same as the one for the last constant. One can consequently +derive the following property. + +\paragraph{Pruning property:} +\inference{\frac{\WF{E; \Def{\Delta}{c}{t}{T}}{\Gamma}} + {\WF{E;\Def{\Delta}{c}{t}{T}}{\Delta}}} + + +\section{Inductive Definitions}\label{Cic-inductive-definitions} + +A (possibly mutual) inductive definition is specified by giving the +names and the type of the inductive sets or families to be +defined and the names and types of the constructors of the inductive +predicates. An inductive declaration in the environment can +consequently be represented with two contexts (one for inductive +definitions, one for constructors). + +Stating the rules for inductive definitions in their general form +needs quite tedious definitions. We shall try to give a concrete +understanding of the rules by precising them on running examples. We +take as examples the type of natural numbers, the type of +parameterized lists over a type $A$, the relation which state that +a list has some given length and the mutual inductive definition of trees and +forests. + +\subsection{Representing an inductive definition} +\subsubsection{Inductive definitions without parameters} +As for constants, inductive definitions can be defined in a non-empty +context. \\ +We write \NInd{\Gamma}{\Gamma_I}{\Gamma_C} an inductive +definition valid in a context $\Gamma$, a +context of definitions $\Gamma_I$ and a context of constructors +$\Gamma_C$. +\paragraph{Examples.} +The inductive declaration for the type of natural numbers will be: +\[\NInd{}{\nat:\Set}{\nO:\nat,\nS:\nat\ra\nat}\] +In a context with a variable $A:\Set$, the lists of elements in $A$ is +represented by: +\[\NInd{A:\Set}{\List:\Set}{\Nil:\List,\cons : A \ra \List \ra + \List}\] + Assuming + $\Gamma_I$ is $[I_1:A_1;\ldots;I_k:A_k]$, and $\Gamma_C$ is + $[c_1:C_1;\ldots;c_n:C_n]$, the general typing rules are: + +\bigskip +\inference{\frac{\NInd{\Gamma}{\Gamma_I}{\Gamma_C} \in E + ~~j=1\ldots k}{(I_j:A_j) \in E}} + +\inference{\frac{\NInd{\Gamma}{\Gamma_I}{\Gamma_C} \in E + ~~~~i=1.. n} + {(c_i:\subst{C_i}{I_j}{I_j}_{j=1\ldots k})\in E}} + +\subsubsection{Inductive definitions with parameters} + +We have to slightly complicate the representation above in order to handle +the delicate problem of parameters. +Let us explain that on the example of \List. As they were defined +above, the type \List\ can only be used in an environment where we +have a variable $A:\Set$. Generally one want to consider lists of +elements in different types. For constants this is easily done by abstracting +the value over the parameter. In the case of inductive definitions we +have to handle the abstraction over several objects. + +One possible way to do that would be to define the type \List\ +inductively as being an inductive family of type $\Set\ra\Set$: +\[\NInd{}{\List:\Set\ra\Set}{\Nil:(A:\Set)(\List~A),\cons : (A:\Set)A + \ra (\List~A) \ra (\List~A)}\] +There are drawbacks to this point of view. The +information which says that $(\List~\nat)$ is an inductively defined +\Set\ has been lost. +%\footnote{ +%The interested reader may look at the compare the above definition with the two +%following ones which have very different logical meaning:\\ +%$\NInd{}{\List:\Set}{\Nil:\List,\cons : (A:\Set)A +% \ra \List \ra \List}$ \\ +%$\NInd{}{\List:\Set\ra\Set}{\Nil:(A:\Set)(\List~A),\cons : (A:\Set)A +% \ra (\List~A\ra A) \ra (\List~A)}$.} + +In the system, we keep track in the syntax of the context of +parameters. The idea of these parameters is that they can be +instantiated and still we have an inductive definition for which we +know the specification. + +Formally the representation of an inductive declaration +will be +\Ind{\Gamma}{\Gamma_P}{\Gamma_I}{\Gamma_C} for an inductive +definition valid in a context $\Gamma$ with parameters $\Gamma_P$, a +context of definitions $\Gamma_I$ and a context of constructors +$\Gamma_C$. +The occurrences of the variables of $\Gamma_P$ in the contexts +$\Gamma_I$ and $\Gamma_C$ are bound. + +The definition \Ind{\Gamma}{\Gamma_P}{\;\Gamma_I}{\Gamma_C\;} will be +well-formed exactly when \NInd{\Gamma,\Gamma_P}{\;\Gamma_I}{\Gamma_C\;} is. +If $\Gamma_P$ is $[p_1:P_1;\ldots;p_r:P_r]$, an object in +\Ind{\Gamma}{\Gamma_P}{\Gamma_I}{\Gamma_C} applied to $q_1,\ldots,q_r$ +will behave as the corresponding object of +\NInd{\Gamma}{\substs{\Gamma_I}{p_i}{q_i}{i=1..r}}{\substs{\Gamma_C}{p_i}{q_i}{i=1..r}}. + +\paragraph{Examples} +The declaration for parameterized lists is: +\[\Ind{}{A:\Set}{\List:\Set}{\Nil:\List,\cons : A \ra \List \ra + \List}\] + +The declaration for the length of lists is: +\[\Ind{}{A:\Set}{\Length:(\List~A)\ra \nat\ra\Prop} + {\LNil:(\Length~(\Nil~A)~\nO),\\ + \LCons :(a:A)(l:(\List~A))(n:\nat)(\Length~l~n)\ra (\Length~(\cons~A~a~l)~(\nS~n))}\] + +The declaration for a mutual inductive definition of forests and trees is: +\[\NInd{[]}{\tree:\Set,\forest:\Set} + {\node:\forest \ra \tree, + \emptyf:\forest,\consf:\tree \ra \forest \ra \forest\-}\] + +These representations are the ones obtained as the result of the \Coq\ +declaration: +\begin{coq_example*} +Inductive Set nat := O : nat | S : nat -> nat. +Inductive list [A : Set] : Set := + nil : (list A) | cons : A -> (list A) -> (list A). +\end{coq_example*} +\begin{coq_example*} +Inductive Length [A:Set] : (list A) -> nat -> Prop := + Lnil : (Length A (nil A) O) + | Lcons : (a:A)(l:(list A))(n:nat) + (Length A l n)->(Length A (cons A a l) (S n)). +Mutual Inductive tree : Set := node : forest -> tree +with forest : Set := emptyf : forest | consf : tree -> forest -> forest. +\end{coq_example*} +The inductive declaration in \Coq\ is slightly different from the one +we described theoretically. The difference is that in the type of +constructors the inductive definition is explicitly applied to the +parameters variables. The \Coq\ type-checker verifies that all +parameters are applied in the correct manner in each recursive call. +In particular, the following definition will not be accepted because +there is an occurrence of \List\ which is not applied to the parameter +variable: +\begin{coq_example} +Inductive list [A : Set] : Set := + nil : (list A) | cons : A -> (list A->A) -> (list A). +\end{coq_example} + +\subsection{Types of inductive objects} +We have to give the type of constants in an environment $E$ which +contains an inductive declaration. + +\begin{description} +\item[Ind-Const] Assuming $\Gamma_P$ is $[p_1:P_1;\ldots;p_r:P_r]$, + $\Gamma_I$ is $[I_1:A_1;\ldots;I_k:A_k]$, and $\Gamma_C$ is + $[c_1:C_1;\ldots;c_n:C_n]$, + +\inference{\frac{\Ind{\Gamma}{\Gamma_P}{\Gamma_I}{\Gamma_C} \in E + ~~j=1\ldots k}{(I_j:(p_1:P_1)\ldots(p_r:P_r)A_j) \in E}} + +\inference{\frac{\Ind{\Gamma}{\Gamma_P}{\Gamma_I}{\Gamma_C} \in E + ~~~~i=1.. n} + {(c_i:(p_1:P_1)\ldots(p_r:P_r)\subst{C_i}{I_j}{(I_j~p_1\ldots + p_r)}_{j=1\ldots k})\in E}} +\end{description} + +\paragraph{Example.} +We have $(\List:\Set \ra \Set), (\cons:(A:\Set)A\ra(\List~A)\ra +(\List~A))$, \\ +$(\Length:(A:\Set)(\List~A)\ra\nat\ra\Prop)$, $\tree:\Set$ and $\forest:\Set$. + +From now on, we write $\ListA$ instead of $(\List~A)$ and $\LengthA$ +for $(\Length~A)$. + +%\paragraph{Parameters.} +%%The parameters introduce a distortion between the inside specification +%%of the inductive declaration where parameters are supposed to be +%%instantiated (this representation is appropriate for checking the +%%correctness or deriving the destructor principle) and the outside +%%typing rules where the inductive objects are seen as objects +%%abstracted with respect to the parameters. + +%In the definition of \List\ or \Length\, $A$ is a parameter because +%what is effectively inductively defined is $\ListA$ or $\LengthA$ for +%a given $A$ which is constant in the type of constructors. But when +%we define $(\LengthA~l~n)$, $l$ and $n$ are not parameters because the +%constructors manipulate different instances of this family. + +\subsection{Well-formed inductive definitions} +We cannot accept any inductive declaration because some of them lead +to inconsistent systems. We restrict ourselves to definitions which +satisfy a syntactic criterion of positivity. Before giving the formal +rules, we need a few definitions: + +\paragraph{Definitions}\index{Positivity}\label{Positivity} + +A type $T$ is an {\em arity of sort $s$}\index{Arity} +if it converts to the sort $s$ or to a +product $(x:T)U$ with $U$ an arity of sort $s$. (For instance $A\ra +\Set$ or $(A:\Prop)A\ra \Prop$ are arities of sort respectively \Set\ +and \Prop). +A {\em type of constructor of $I$}\index{Type of constructor} + is either a term $(I~t_1\ldots ~t_n)$ or +$(x:T)C$ with $C$ a {\em type of constructor of $I$}. + +\smallskip + +The type of constructor $T$ will be said to {\em satisfy the positivity +condition} for a constant $X$ in the following cases: + +\begin{itemize} +\item $T=(X~t_1\ldots ~t_n)$ and $X$ does not occur free in +any $t_i$ +\item $T=(x:T)U$ and $X$ occurs only strictly positively in $T$ and +the type $U$ satisfies the positivity condition for $X$ +\end{itemize} + +The constant $X$ {\em occurs strictly positively} in $T$ in the +following cases: + +\begin{itemize} +\item $X$ does not occur in $T$ +\item $T$ converts to $(X~t_1 \ldots ~t_n)$ and $X$ does not occur in any of $t_i$ +\item $T$ converts to $(x:U)V$ and $X$ does not occur in type $U$ but occurs strictly +positively in type $V$ +\item $T$ converts to $(I~a_1 \ldots ~a_m ~ t_1 \ldots ~t_p)$ where $I$ is the name of an +inductive declaration of the form $\Ind{\Gamma}{[p_1:P_1;\ldots;p_m:P_m]}{[I:A]}{[c_1:C_1;\ldots;c_n:C_n]}$ +(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 types of constructor $C_i\{p_j/a_j\}_{j=1\ldots m}$ of $I$ +satisfy the imbricated positivity condition for $X$ +%\item more generally, when $T$ is not a type, $X$ occurs strictly +%positively in $T[x:U]u$ if $X$ does not occur in $U$ but occurs +%strictly positively in $u$ +\end{itemize} + +The type constructor $T$ of $I$ {\em satisfies the imbricated +positivity condition} for a constant $X$ in the following +cases: + +\begin{itemize} +\item $T=(I~t_1\ldots ~t_n)$ and $X$ does not occur in +any $t_i$ +\item $T=(x:T)U$ and $X$ occurs only strictly positively in $T$ and +the type $U$ satisfies the imbricated positivity condition for $X$ +\end{itemize} + +\paragraph{Example} +$X$ occurs strictly positively in $A\ra X$ or $X*A$ or $({\tt list} +X)$ but not in $X \ra A$ or $(X \ra A)\ra A$ assuming the notion of +product and lists were already defined. Assuming $X$ has arity ${\tt +nat \ra Prop}$ and {\tt ex} is inductively defined existential +quantifier, the occurrence of $X$ in ${\tt (ex~ nat~ [n:nat](X~ n))}$ is +also strictly positive.\\ + +\paragraph{Correctness rules.} +We shall now describe the rules allowing the introduction of a new +inductive definition. + +\begin{description} +\item[W-Ind] Let $E$ be an environment and + $\Gamma,\Gamma_P,\Gamma_I,\Gamma_C$ are contexts such that + $\Gamma_I$ is $[I_1:A_1;\ldots;I_k:A_k]$ and $\Gamma_C$ is + $[c_1:C_1;\ldots;c_n:C_n]$. \\[3mm] +\inference{ + \frac{ + (\WTE{\Gamma;\Gamma_P}{A_j}{s'_j})_{j=1\ldots k} + ~~ (\WTE{\Gamma;\Gamma_P;\Gamma_I}{C_i}{s_{p_i}})_{i=1\ldots n} +} + {\WF{E;\Ind{\Gamma}{\Gamma_P}{\Gamma_I}{\Gamma_C}}{\Gamma}}}\\ +providing the following side conditions hold: +\begin{itemize} +\item $k>0$, $I_j$, $c_i$ are different names for $j=1\ldots k$ and $i=1\ldots n$, +\item for $j=1\ldots k$ we have $A_j$ is an arity of sort $s_j$ and $I_j + \notin \Gamma \cup E$, +\item for $i=1\ldots n$ we have $C_i$ is a type of constructor of + $I_{p_i}$ which satisfies the positivity condition for $I_1 \ldots I_k$ + and $c_i \notin \Gamma \cup E$. +\end{itemize} +\end{description} +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 impredicative sorts +(\Prop\ or \Set) but may generate constraints between universes. + + +%We shall assume for the following definitions that, if necessary, we +%annotated the type of constructors such that we know if the argument +%is recursive or not. We shall write the type $(x:_R T)C$ if it is +%a recursive argument and $(x:_P T)C$ if the argument is not recursive. + +\subsection{Destructors} +The specification of inductive definitions with arities and +constructors is quite natural. But we still have to say how to use an +object in an inductive type. + +This problem is rather delicate. There are actually several different +ways to do that. Some of them are logically equivalent but not always +equivalent from the computational point of view or from the user point +of view. + +From the computational point of view, we want to be able to define a +function whose domain is an inductively defined type by using a +combination of case analysis over the possible constructors of the +object and recursion. + +Because we need to keep a consistent theory and also we prefer to keep +a strongly normalising reduction, we cannot accept any sort of +recursion (even terminating). So the basic idea is to restrict +ourselves to primitive recursive functions and functionals. + +For instance, assuming a parameter $A:\Set$ exists in the context, we +want to build a function \length\ of type $\ListA\ra \nat$ which +computes the length of the list, so such that $(\length~\Nil) = \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. + +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 $(P~m)$ for $m$ in an inductive definition it is +enough to enumerate all the cases where $m$ starts with a different +constructor. + +In case the inductive definition is effectively a recursive one, we +want to capture the extra property that we have built the smallest +fixed point of this recursive equation. This says that we are only +manipulating finite objects. This analysis provides induction +principles. + +For instance, in order to prove $(l:\ListA)(\LengthA~l~(\length~l))$ +it is enough to prove: + +\noindent $(\LengthA~\Nil~(\length~\Nil))$ and + +\smallskip +$(a:A)(l:\ListA)(\LengthA~l~(\length~l)) \ra +(\LengthA~(\cons~A~a~l)~(\length~(\cons~A~a~l)))$. +\smallskip + +\noindent which given the conversion equalities satisfied by \length\ is the +same as proving: +$(\LengthA~\Nil~\nO)$ and $(a:A)(l:\ListA)(\LengthA~l~(\length~l)) \ra +(\LengthA~(\cons~A~a~l)~(\nS~(\length~l)))$. + +One conceptually simple way to do that, following the basic scheme +proposed by Martin-L\"of in his Intuitionistic Type Theory, is to +introduce for each inductive definition an elimination operator. At +the logical level it is a proof of the usual induction principle and +at the computational level it implements a generic operator for doing +primitive recursion over the structure. + +But this operator is rather tedious to implement and use. We choose in +this version of Coq to factorize the operator for primitive recursion +into two more primitive operations as was first suggested by Th. Coquand +in~\cite{Coq92}. One is the definition by case +analysis. The second one is a definition by guarded fixpoints. + +\subsubsection{The {\tt Cases\ldots of \ldots end} construction.} +\label{Caseexpr} +\index{Cases@{\tt Cases\ldots of\ldots end}} + +The basic idea of this destructor operation is that we have an object +$m$ in an inductive type $I$ and we want to prove a property $(P~m)$ +which in general depends on $m$. For this, it is enough to prove the +property for $m = (c_i~u_1\ldots u_{p_i})$ for each constructor of $I$. + +This proof will be denoted by a generic term: +\[\Case{P}{m}{(c_1~x_{11}~...~x_{1p_1}) \mbox{\tt =>} f_1 \ldots +(c_n~x_{n1}~|~...~|~x_{np_n}) \mbox{\tt =>} f_n }\] +In this expression, if $m$ is a term built from a constructor +$(c_i~u_1\ldots u_{p_i})$ then the expression will behave as it is specified +with $i$-th branch and will reduce to $f_i$ where the $x_{i1}$\ldots $x_{ip_i}$ are +replaced by the $u_1\ldots u_p$ according to +the $\iota$-reduction.\\ + +This is the basic idea which is generalized to the case where $I$ is +an inductively defined $n$-ary relation (in which case the property +$P$ to be proved will be a $n+1$-ary relation). + +\paragraph{Non-dependent elimination.} +When defining a function by case analysis, we build an object of type $I +\ra C$ and the minimality principle on an inductively defined logical +predicate of type $A \ra \Prop$ is often used to prove a property +$(x:A)(I~x)\ra (C~x)$. This is a particular case of the dependent +principle that we stated before with a predicate which does not depend +explicitly on the object in the inductive definition. + +For instance, a function testing whether a list is empty +can be +defined as: + +\[[l:\ListA]\Case{[H:\ListA]\bool}{l}{\Nil~ \mbox{\tt =>}~\true~ |~ (\cons~a~m)~ \mbox{\tt =>}~\false}\] +\noindent {\bf Remark. } In the system \Coq\ the expression above, can be +written without mentioning +the dummy abstraction: +\Case{\bool}{l}{\Nil~ \mbox{\tt =>}~\true~ |~ (\cons~a~m)~ + \mbox{\tt =>}~ \false} + +\paragraph{Allowed elimination sorts.} +\index{Elimination sorts} + +An important question for building the typing rule for {\tt Case} is +what can be the type of $P$ with respect to the type of the inductive +definitions. + +Remembering that the elimination builds an object in $(P~m)$ from an +object in $m$ in type $I$ it is clear that we cannot allow any combination. + +For instance we cannot in general have $I$ has type \Prop\ +and $P$ has type $I\ra \Set$, because it will mean to build an informative +proof of type $(P~m)$ doing a case analysis over a non-computational +object that will disappear in the extracted program. +But the other way is safe +with respect to our interpretation we can have $I$ a computational +object and $P$ a non-computational one, it just corresponds to proving a +logical property of a computational object. + +Also if $I$ is in one of the sorts \{\Prop, \Set\}, one cannot in +general allow an elimination over a bigger sort such as \Type. +But this operation is safe whenever $I$ is a {\em small + inductive} type, which means that all the types of constructors of +$I$ are small with the following definition:\\ +$(I~t_1\ldots t_s)$ is a {\em small type of constructor} and $(x:T)C$ is a +small type of constructor if $C$ is and if $T$ has type \Prop\ or +\Set. +\index{Small inductive type} + +We call this particular elimination which gives the possibility to +compute a type by induction on the structure of a term, a {\em strong + elimination}\index{Strong elimination}. + + +We define now a relation \compat{I:A}{B} between an inductive +definition $I$ of type $A$, an arity $B$ which says that an object in +the inductive definition $I$ can be eliminated for proving a property +$P$ of type $B$. + +The \compat{I:A}{B} is defined as the smallest relation satisfying the +following rules: + +\begin{description} +\item[Prod] \inference{\frac{\compat{(I~x):A'}{B'}} + {\compat{I:(x:A)A'}{(x:A)B'}}} +\item[\Prop] \inference{\compat{I:\Prop}{I\ra\Prop}~~~~~ + \frac{I \mbox{~is a singleton definition}}{\compat{I:\Prop}{I\ra \Set}}} + +\item[\Set] \inference{\frac{s \in + \{\Prop, \Set\}}{\compat{I:\Set}{I\ra s}} +~~~~\frac{I \mbox{~is a small inductive definition}~~~~s \in + \{\Type(i)\}} + {\compat{I:\Set}{I\ra s}}} +\item[\Type] \inference{\frac{ + s \in \{\Prop,\Set,\Type(j)\}}{\compat{I:\Type(i)}{I\ra s}}} +\end{description} + +\paragraph{Notations.} +We write \compat{I}{B} for \compat{I:A}{B} where $A$ is the type of +$I$. + +%\paragraph{Warning: strong elimination} +%\index{Elimination!Strong elimination} +%In previous versions of Coq, for a small inductive definition, only the +%non-informative strong elimination on \Type\ was allowed, because +%strong elimination on \Typeset\ was not compatible with the current +%extraction procedure. In this version, strong elimination on \Typeset\ +%is accepted but a dummy element is extracted from it and may generate +%problems if extracted terms are explicitly used such as in the +%{\tt Program} tactic or when extracting ML programs. + +\paragraph{Singleton elimination} +\index{Elimination!Singleton elimination} + +A {\em singleton definition} has always an informative content, +even if it is a proposition. + +A {\em singleton +definition} has only one constructor and all the argument of this +constructor are non informative. In that case, there is a canonical +way to interpret the informative extraction on an object in that type, +such that the elimination on sort $s$ is legal. Typical examples are +the conjunction of non-informative propositions and the equality. In +that case, the term \verb!eq_rec! which was defined as an axiom, is +now a term of the calculus. +\begin{coq_example} +Print eq_rec. +Extraction eq_rec. +\end{coq_example} + +\paragraph{Type of branches.} +Let $c$ be a term of type $C$, we assume $C$ is a type of constructor +for an inductive definition $I$. Let $P$ be a term that represents the +property to be proved. +We assume $r$ is the number of parameters. + +We define a new type \CI{c:C}{P} which represents the type of the +branch corresponding to the $c:C$ constructor. +\[ +\begin{array}{ll} +\CI{c:(I_i~p_1\ldots p_r\ t_1 \ldots t_p)}{P} &\equiv (P~t_1\ldots ~t_p~c) \\[2mm] +\CI{c:(x: T)C}{P} &\equiv (x:T)\CI{(c~x):C}{P} +\end{array} +\] +We write \CI{c}{P} for \CI{c:C}{P} with $C$ the type of $c$. + +\paragraph{Examples.} +For $\ListA$ the type of $P$ will be $\ListA\ra s$ for $s \in +\{\Prop,\Set,\Type(i)\}$. \\ +$ \CI{(\cons~A)}{P} \equiv +(a:A)(l:\ListA)(P~(\cons~A~a~l))$. + +For $\LengthA$, the type of $P$ will be +$(l:\ListA)(n:\nat)(\LengthA~l~n)\ra \Prop$ and the expression +\CI{(\LCons~A)}{P} is defined as:\\ +$(a:A)(l:\ListA)(n:\nat)(h:(\LengthA~l~n))(P~(\cons~A~a~l)~(\nS~n)~(\LCons~A~a~l~n~l))$.\\ +If $P$ does not depend on its third argument, we find the more natural +expression:\\ +$(a:A)(l:\ListA)(n:\nat)(\LengthA~l~n)\ra(P~(\cons~A~a~l)~(\nS~n))$. + +\paragraph{Typing rule.} + +Our very general destructor for inductive definition enjoys the +following typing rule (we write {\Case{P}{c}{[x_{11}:T_{11}]\ldots[x_{1p_1}:T_{1p_1}]f_1\ldots [x_{n1}:T_{n1}]\ldots[x_{np_n}:T_{np_n}f_n} for \Case{P}{m}{(c_1~x_{11}~...~x_{1p_1}) \mbox{\tt =>} f_1 \ldots +(c_n~x_{n1}~|~...~|~x_{np_n}) \mbox{\tt =>} f_n }}): + +\begin{description} +\item[Case] \label{elimdep} \index{Typing rules!Case} +\inference{ +\frac{\WTEG{c}{(I~q_1\ldots q_r~t_1\ldots t_s)}~~ + \WTEG{P}{B}~~\compat{(I~q_1\ldots q_r)}{B} + ~~ +(\WTEG{f_i}{\CI{(c_{p_i}~q_1\ldots q_r)}{P}})_{i=1\ldots l}} +{\WTEG{\Case{P}{c}{f_1\ldots f_l}}{(P\ t_1\ldots t_s\ c)}}}%\\[3mm] + +provided $I$ is an inductive type in a declaration +\Ind{\Delta}{\Gamma_P}{\Gamma_I}{\Gamma_C} with $|\Gamma_P| = r$, +$\Gamma_C = [c_1:C_1;\ldots;c_n:C_n]$ and $c_{p_1}\ldots c_{p_l}$ are the +only constructors of $I$. +\end{description} + +\paragraph{Example.} +For \List\ and \Length\ the typing rules for the {\tt Case} expression +are (writing just $t:M$ instead of \WTEG{t}{M}, the environment and +context being the same in all the judgments). + +\[\frac{l:\ListA~~P:\ListA\ra s~~~f_1:(P~(\Nil~A))~~ + f_2:(a:A)(l:\ListA)(P~(\cons~A~a~l))} + {\Case{P}{l}{f_1~f_2}:(P~l)}\] + +\[\frac{ + \begin{array}[b]{c} +H:(\LengthA~L~N) \\ P:(l:\ListA)(n:\nat)(\LengthA~l~n)\ra + \Prop\\ + f_1:(P~(\Nil~A)~\nO~\LNil) \\ + f_2:(a:A)(l:\ListA)(n:\nat)(h:(\LengthA~l~n))(P~(\cons~A~a~n)~(\nS~n)~(\LCons~A~a~l~n~h)) + \end{array}} + {\Case{P}{H}{f_1~f_2}:(P~L~N~H)}\] + +\paragraph{Definition of $\iota$-reduction.}\label{iotared} +\index{iota-reduction@$\iota$-reduction} +We still have to define the $\iota$-reduction in the general case. + +A $\iota$-redex is a term of the following form: +\[\Case{P}{(c_{p_i}~q_1\ldots q_r~a_1\ldots a_m)}{f_1\ldots + f_l}\] +with $c_{p_i}$ the $i$-th constructor of the inductive type $I$ with $r$ +parameters. + +The $\iota$-contraction of this term is $(f_i~a_1\ldots a_m)$ leading +to the general reduction rule: +\[ \Case{P}{(c_{p_i}~q_1\ldots q_r~a_1\ldots a_m)}{f_1\ldots + f_n} \triangleright_{\iota} (f_i~a_1\ldots a_m) \] + +\subsection{Fixpoint definitions} +\label{Fix-term} \index{Fix@{\tt Fix}} +The second operator for elimination is fixpoint definition. +This fixpoint may involve several mutually recursive definitions. +The basic syntax for a recursive set of declarations is +\[\Fix{}{f_1:A_1:=t_1 \ldots f_n:A_n:=t_n}\] +The terms are obtained by projections from this set of declarations +and are written $\Fix{f_i}{f_1:A_1:=t_1 \ldots f_n:A_n:=t_n}$ + +\subsubsection{Typing rule} +The typing rule is the expected one for a fixpoint. + +\begin{description} +\item[Fix] \index{Typing rules!Fix} +\inference{\frac{(\WTEG{A_i}{s_i})_{i=1\ldots n}~~~~ + (\WTE{\Gamma,f_1:A_1,\ldots,f_n:A_n}{t_i}{A_i})_{i=1\ldots n}} + {\WTEG{\Fix{f_i}{f_1:A_1:=t_1 \ldots f_n:A_n:=t_n}}{A_i}}} +\end{description} + +Any fixpoint definition cannot be accepted because non-normalizing terms +will lead to 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 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 +\[(P:\nat\ra\Prop)(P~\nO)\ra((n:\nat)(P~n)\ra(P~(\nS~n)))\ra(n:\nat)(P~n)\] +can be represented by the term: +\[\begin{array}{l} +[P:\nat\ra\Prop][f:(P~\nO)][g:(n:\nat)(P~n)\ra(P~(\nS~n))]\\ +\Fix{h}{h:(n:\nat)(P~n):=[n:\nat]\Case{P}{n}{f~[p:\nat](g~p~(h~p))}} +\end{array} +\] + +Before accepting a fixpoint definition as being correctly typed, we +check that the definition is ``guarded''. A precise analysis of this +notion can be found in~\cite{Gim94}. + +The first stage is to precise on which argument the fixpoint will be +decreasing. The type of this argument should be an inductive +definition. + +For doing this the syntax of fixpoints is extended and becomes + \[\Fix{f_i}{f_1/k_1:A_1:=t_1 \ldots f_n/k_n:A_n:=t_n}\] +where $k_i$ are positive integers. +Each $A_i$ should be a type (reducible to a term) starting with at least +$k_i$ products $(y_1:B_1)\ldots (y_{k_i}:B_{k_i}) A'_i$ and $B_{k_i}$ +being an instance of an inductive definition. + +Now in the definition $t_i$, if $f_j$ occurs then it should be applied +to at least $k_j$ arguments and the $k_j$-th argument should be +syntactically recognized as structurally smaller than $y_{k_i}$ + + +The definition of being structurally smaller is a bit technical. +One needs first to define the notion of +{\em recursive arguments of a constructor}\index{Recursive arguments}. +For an inductive definition \Ind{\Gamma}{\Gamma_P}{\Gamma_I}{\Gamma_C}, +the type of a constructor $c$ have the form +$(p_1:P_1)\ldots(p_r:P_r)(x_1:T_1)\ldots (x_r:T_r)(I_j~p_1\ldots +p_r~t_1\ldots t_s)$ the recursive arguments will correspond to $T_i$ in +which one of the $I_l$ occurs. + + +The main rules for being structurally smaller are the following:\\ +Given a variable $y$ of type an inductive +definition in a declaration +\Ind{\Gamma}{\Gamma_P}{\Gamma_I}{\Gamma_C} +where $\Gamma_I$ is $[I_1:A_1;\ldots;I_k:A_k]$, and $\Gamma_C$ is + $[c_1:C_1;\ldots;c_n:C_n]$. +The terms structurally smaller than $y$ are: +\begin{itemize} +\item $(t~u), [x:u]t$ when $t$ is structurally smaller than $y$ . +\item \Case{P}{c}{f_1\ldots f_n} when each $f_i$ is structurally + smaller than $y$. \\ + If $c$ is $y$ or is structurally smaller than $y$, its type is an inductive + definition $I_p$ part of the inductive + declaration corresponding to $y$. + Each $f_i$ corresponds to a type of constructor $C_q \equiv + (y_1:B_1)\ldots (y_k:B_k)(I~a_1\ldots a_k)$ and can consequently be + written $[y_1:B'_1]\ldots [y_k:B'_k]g_i$. + ($B'_i$ is obtained from $B_i$ by substituting parameters variables) + the variables $y_j$ occurring + in $g_i$ corresponding to recursive arguments $B_i$ (the ones in + which one of the $I_l$ occurs) are structurally smaller than $y$. +\end{itemize} +The following definitions are correct, we enter them using the +{\tt Fixpoint} command as described in section~\ref{Fixpoint} and show +the internal representation. +\begin{coq_example} +Fixpoint plus [n:nat] : nat -> nat := + [m:nat]Case n of m [p:nat](S (plus p m)) end. +Print plus. +Fixpoint lgth [A:Set;l:(list A)] : nat := + Case l of O [a:A][l':(list A)](S (lgth A l')) end. +Print lgth. +Fixpoint sizet [t:tree] : nat + := Case t of [f:forest](S (sizef f)) end +with sizef [f:forest] : nat + := Case f of O [t:tree][f:forest](plus (sizet t) (sizef f)) end. +Print sizet. +\end{coq_example} + + +\subsubsection{Reduction rule} +\index{iota-reduction@$\iota$-reduction} +Let $F$ be the set of declarations: $f_1/k_1:A_1:=t_1 \ldots +f_n/k_n:A_n:=t_n$. +The reduction for fixpoints is: +\[ (\Fix{f_i}{F}~a_1\ldots +a_{k_i}) \triangleright_{\iota} \substs{t_i}{f_k}{\Fix{f_k}{F}}{k=1\ldots n}\] +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. + +We can illustrate this behavior on examples. +\begin{coq_example} +Goal (n,m:nat)(plus (S n) m)=(S (plus n m)). +Reflexivity. +Abort. +Goal (f:forest)(sizet (node f))=(S (sizef f)). +Reflexivity. +Abort. +\end{coq_example} +But assuming the definition of a son function from \tree\ to \forest: +\begin{coq_example} + Definition sont : tree -> forest := [t]Case t of [f]f end. +\end{coq_example} +The following is not a conversion but can be proved after a case analysis. +\begin{coq_example} +Goal (t:tree)(sizet t)=(S (sizef (sont t))). +(* this one fails *) +Reflexivity. +Destruct t. +Reflexivity. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\subsubsection{The {\tt Match \ldots with \ldots end} expression} +\label{Matchexpr} +%\paragraph{A unary {\tt Match\ldots with \ldots end}.} +\index{Match...with...end@{\tt Match \ldots with \ldots end}} +The {\tt Match} operator which was a primitive notion in older +presentations of the Calculus of Inductive Constructions is now just a +macro definition which generates the good combination of {\tt Case} +and {\tt Fix} operators in order to generate an operator for primitive +recursive definitions. It always considers an inductive definition as +a single inductive definition. + +The following examples illustrates this feature. +\begin{coq_example} +Definition nat_pr : (C:Set)C->(nat->C->C)->nat->C + :=[C,x,g,n]Match n with x g end. +Print nat_pr. +\end{coq_example} +\begin{coq_example} +Definition forest_pr + : (C:Set)C->(tree->forest->C->C)->forest->C + := [C,x,g,n]Match n with x g end. +\end{coq_example} + +% Cet exemple faisait error (HH le 12/12/96), j'ai change pour une +% version plus simple +%\begin{coq_example} +%Definition forest_pr +% : (P:forest->Set)(P emptyf)->((t:tree)(f:forest)(P f)->(P (consf t f))) +% ->(f:forest)(P f) +% := [C,x,g,n]Match n with x g end. +%\end{coq_example} + +The principles of mutual induction can be automatically generated +using the {\tt Scheme} command described in section~\ref{Scheme}. + +\section{Coinductive types} +The implementation contains also coinductive definitions, which are +types inhabited by infinite objects. +%They are described inchapter~\ref{Coinductives}. + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: + + diff --git a/doc/RefMan-coi.tex b/doc/RefMan-coi.tex new file mode 100755 index 000000000..7de3e69fe --- /dev/null +++ b/doc/RefMan-coi.tex @@ -0,0 +1,400 @@ +%\documentstyle[11pt,../tools/coq-tex/coq]{article} +%\input{title} + +%\include{macros} +%\begin{document} + +%\coverpage{Co-inductive types in Coq}{Eduardo Gim\'enez} +\chapter{Co-inductive types in Coq}\label{Coinductives} + +%\begin{abstract} +{\it Co-inductive} types are types whose elements may not be well-founded. +A formal study of the Calculus of Constructions extended by +co-inductive types has been presented +in \cite{Gim94}. It is based on the notion of +{\it guarded definitions} introduced by Th. Coquand +in \cite{Coquand93}. The implementation is by E. Gim\'enez. +%\end{abstract} + +\section{A short introduction to co-inductive types} + +We assume that the reader is rather familiar with inductive types. +These types are characterized by their {\it constructors}, which can be +regarded as the basic methods from which the elements +of the type can be built up. It is implicit in the definition +of an inductive type that +its elements are the result of a {\it finite} number of +applications of its constructors. Co-inductive types arise from +relaxing this implicit condition and admitting that an element of +the type can also be introduced by a non-ending (but effective) process +of construction defined in terms of the basic methods which characterize the +type. So we could think in the wider notion of types defined by +constructors (let us call them {\it recursive types}) and classify +them into inductive and co-inductive ones, depending on whether or not +we consider non-ending methods as admissible for constructing elements +of the type. Note that in both cases we obtain a ``closed type'', all whose +elements are pre-determined in advance (by the constructors). When we +know that $a$ is an element of a recursive type (no matter if it is +inductive or co-inductive) what we know is that it is the result of applying +one of the basic forms of construction allowed for the type. +So the more primitive way of eliminating an element of a recursive type is +by case analysis, i.e. by considering through which constructor it could have +been introduced. In the case of inductive sets, the additional knowledge that +constructors can be applied only a finite number of times provide +us with a more powerful way of eliminating their elements, say, +the principle of +induction. This principle is obviously not valid for co-inductive types, +since it is just the expression of this extra knowledge attached to inductive +types. + + +An example of a co-inductive type is the type of infinite sequences formed with +elements of type $A$, or streams for shorter. In Coq, +it can be introduced using the \verb!CoInductive! command~: +\begin{coq_example} +CoInductive Set Stream [A:Set] := cons : A->(Stream A)->(Stream A). +\end{coq_example} + +The syntax of this command is the same as the +command \verb!Inductive! (cf. section +\ref{gal_Inductive_Definitions}). +Definition of mutually coinductive types are possible. + +As was already said, there are not principles of +induction for co-inductive sets, the only way of eliminating these +elements is by case analysis. +In the example of streams, this elimination principle can be +used for instance to define the well known +destructors on streams $\hd : (\Str\;A)\rightarrow A$ +and $\tl: (\Str\;A)\rightarrow (\Str\;A)$ : +\begin{coq_example} +Section Destructors. +Variable A : Set. +Definition hd := [x:(Stream A)]Cases x of (cons a s) => a end. +Definition tl := [x:(Stream A)]Cases x of (cons a s) => s end. +\end{coq_example} +\begin{coq_example*} +End Destructors. +\end{coq_example*} + +\subsection{Non-ending methods of construction} + +At this point the reader should have realized that we have left unexplained +what is a ``non-ending but effective process of +construction'' of a stream. In the widest sense, a +method is a non-ending process of construction if we can eliminate the +stream that it introduces, in other words, if we can reduce +any case analysis on it. In this sense, the following ways of +introducing a stream are not acceptable. +\begin{center} +$\zeros = (\cons\;\nat\;\nO\;(\tl\;\zeros))\;\;:\;\;(\Str\;\nat)$\\[12pt] +$\filter\;(\cons\;A\;a\;s) = \si\;\;(P\;a)\;\;\alors\;\;(\cons\;A\;a\;(\filter\;s))\;\;\sinon\;\;(\filter\;s) )\;\;:\;\;(\Str\;A)$ +\end{center} +\noindent The former it is not valid since the stream can not be eliminated +to obtain its tail. In the latter, a stream is naively defined as +the result of erasing from another (arbitrary) stream +all the elements which does not verify a certain property $P$. This +does not always makes sense, for example it does not when all the elements +of the stream verify $P$, in which case we can not eliminate it to +obtain its head\footnote{Note that there is no notion of ``the empty +stream'', a stream is always infinite and build by a \texttt{cons}.}. +On the contrary, the following definitions are acceptable methods for +constructing a stream~: +\begin{center} +$\zeros = (\cons\;\nat\;\nO\;\zeros)\;\;:\;\;(\Str\;\nat)\;\;\;(*)$\\[12pt] +$(\from\;n) = (\cons\;\nat\;n\;(\from\;(\nS\;n)))\;:\;(\Str\;\nat)$\\[12pt] +$\alter = (\cons\;\bool\;\true\;(\cons\;\bool\;\false\;\alter))\;:\;(\Str\;\bool)$. +\end{center} +\noindent The first one introduces a stream containing all the natural numbers +greater than a given one, and the second the stream which infinitely +alternates the booleans true and false. + +In general it is not evident to realise when a definition can +be accepted or not. However, there is a class of definitions that +can be easily recognised as being valid : those +where (1) all the recursive calls of the method are done +after having explicitly mentioned which is (at least) the first constructor +to start building the element, and (2) no other +functions apart from constructors are applied to recursive calls. +This class of definitions is usually +referred as {\it guarded-by-constructors} +definitions \cite{Coquand93,Gim94}. +The methods $\from$ +and $\alter$ are examples of definitions which are guarded by constructors. +The definition of function $\filter$ is not, because there is no +constructor to guard +the recursive call in the {\it else} branch. Neither is the one of +$\zeros$, since there is function applied to the recursive call +which is not a constructor. However, there is a difference between +the definition of $\zeros$ and $\filter$. The former may be seen as a +wrong way of characterising an object which makes sense, and it can +be reformulated in an admissible way using the equation (*). On the contrary, +the definition of +$\filter$ can not be patched, since is the idea itself +of traversing an infinite +construction searching for an element whose existence is not ensured +which does not make sense. + + + +Guarded definitions are exactly the kind of non-ending process of +construction which are allowed in Coq. The way of introducing +a guarded definition in Coq is using the special command +{\tt CoFixpoint}. This command verifies that the definition introduces an +element of a co-inductive type, and checks if it is guarded by constructors. +If we try to +introduce the definitions above, $\from$ and $\alter$ will be accepted, +while $\zeros$ and $\filter$ will be rejected giving some explanation +about why. +\begin{coq_example} +CoFixpoint zeros : (Stream nat) := (cons nat O (tl nat zeros)). +CoFixpoint zeros : (Stream nat) := (cons nat O zeros). +CoFixpoint from : nat->(Stream nat) := [n:nat](cons nat n (from (S n))). +\end{coq_example} + +As in the \verb!Fixpoint! command (cf. section~\ref{Fixpoint}), it is possible +to introduce a block of mutually dependent methods. The general syntax +for this case is : + +{\tt CoFixpoint {\ident$_1$} :{\term$_1$} := {\term$_1'$}\\ + with\\ + \mbox{}\hspace{0.1cm} $\ldots$ \\ + with {\ident$_m$} : {\term$_m$} := {\term$_m'$}} + + +\subsection{Non-ending methods and reduction} + +The elimination of a stream introduced by a \verb!CoFixpoint! definition +is done lazily, i.e. its definition can be expanded only when it occurs +at the head of an application which is the argument of a case expression. +Isolately it is considered as a canonical expression which +is completely evaluated. We can test this using the command \verb!Compute! +to calculate the normal forms of some terms~: +\begin{coq_example} +Eval Compute in (from O). +Eval Compute in (hd nat (from O)). +Eval Compute in (tl nat (from O)). +\end{coq_example} +\noindent Thus, the equality +$(\from\;n)\equiv(\cons\;\nat\;n\;(\from \; (\S\;n)))$ +does not hold as definitional one. Nevertheless, it can be proved +as a propositional equality, in the sense of Leibniz's equality. +The version {\it à la Leibniz} of the equality above follows from +a general lemma stating that eliminating and then re-introducing a stream +yields the same stream. +\begin{coq_example} +Lemma unfold_Stream : + (x:(Stream nat))(x=(Cases x of (cons a s) => (cons nat a s) end)). +\end{coq_example} + +\noindent The proof is immediate from the analysis of +the possible cases for $x$, which transforms +the equality in a trivial one. + +\begin{coq_example} +Destruct x. +Trivial. +\end{coq_example} +\begin{coq_eval} +Save. +\end{coq_eval} +The application of this lemma to $(\from\;n)$ puts this +constant at the head of an application which is an argument +of a case analysis, forcing its expansion. +We can test the type of this application using Coq's command \verb!Check!, +which infers the type of a given term. +\begin{coq_example} +Check [n:nat](unfold_Stream (from n)). +\end{coq_example} + \noindent Actually, The elimination of $(\from\;n)$ has actually +no effect, because it is followed by a re-introduction, +so the type of this application is in fact +definitionally equal to the +desired proposition. We can test this computing +the normal form of the application above to see its type. +\begin{coq_example} +Transparent unfold_Stream. +Eval Compute in [n:nat](unfold_Stream (from n)). +\end{coq_example} + + +\section{Reasoning about infinite objects} + +At a first sight, it might seem that +case analysis does not provide a very powerful way +of reasoning about infinite objects. In fact, what we can prove about +an infinite object using +only case analysis is just what we can prove unfolding its method +of construction a finite number of times, which is not always +enough. Consider for example the following method for appending +two streams~: +\begin{coq_example} +Variable A:Set. +CoFixpoint conc : (Stream A)->(Stream A)->(Stream A) + := [s1,s2:(Stream A)](cons A (hd A s1) (conc (tl A s1) s2)). +\end{coq_example} + +Informally speaking, we expect that for all pair of streams $s_1$ and $s_2$, +$(\conc\;s_1\;s_2)$ +defines the ``the same'' stream as $s_1$, +in the sense that if we would be able to unfold the definition +``up to the infinite'', we would obtain definitionally equal normal forms. +However, no finite unfolding of the definitions gives definitionally +equal terms. Their equality can not be proved just using case analysis. + + +The weakness of the elimination principle proposed for infinite objects +contrast with the power provided by the inductive +elimination principles, but it is not actually surprising. It just means +that we can not expect to prove very interesting things about infinite +objects doing finite proofs. To take advantage of infinite objects we +have to consider infinite proofs as well. For example, +if we want to catch up the equality between $(\conc\;s_1\;s_2)$ and +$s_1$ we have to introduce first the type of the infinite proofs +of equality between streams. This is a +co-inductive type, whose elements are build up from a +unique constructor, requiring a proof of the equality of the +heads of the streams, and an (infinite) proof of the equality +of their tails. + +\begin{coq_example} +CoInductive EqSt : (Stream A)->(Stream A)->Prop := + eqst : (s1,s2:(Stream A)) + (hd A s1)=(hd A s2)-> + (EqSt (tl A s1) (tl A s2))->(EqSt s1 s2). +\end{coq_example} +\noindent Now the equality of both streams can be proved introducing +an infinite object of type + +\noindent $(\EqSt\;s_1\;(\conc\;s_1\;s_2))$ by a \verb!CoFixpoint! +definition. +\begin{coq_example} +CoFixpoint eqproof : (s1,s2:(Stream A))(EqSt s1 (conc s1 s2)) + := [s1,s2:(Stream A)] + (eqst s1 (conc s1 s2) + (refl_equal A (hd A (conc s1 s2))) (eqproof (tl A s1) s2)). +\end{coq_example} +\begin{coq_eval} +Reset eqproof. +\end{coq_eval} +\noindent Instead of giving an explicit definition, +we can use the proof editor of Coq to help us in +the construction of the proof. +A tactic \verb!Cofix! allows to place a \verb!CoFixpoint! definition +inside a proof. +This tactic introduces a variable in the context which has +the same type as the current goal, and its application stands +for a recursive call in the construction of the proof. If no name is +specified for this variable, the name of the lemma is chosen by +default. +%\pagebreak + +\begin{coq_example} +Lemma eqproof : (s1,s2:(Stream A))(EqSt s1 (conc s1 s2)). +Cofix. +\end{coq_example} + +\noindent An easy (and wrong!) way of finishing the proof is just to apply the +variable \verb!eqproof!, which has the same type as the goal. + +\begin{coq_example} +Intros. +Apply eqproof. +\end{coq_example} + +\noindent The ``proof'' constructed in this way +would correspond to the \verb!CoFixpoint! definition +\begin{coq_example*} +CoFixpoint eqproof : (s1:(Stream A))(s2:(Stream A))(EqSt s1 (conc s1 s2)) + := eqproof. +\end{coq_example*} + +\noindent which is obviously non-guarded. This means that +we can use the proof editor to +define a method of construction which does not make sense. However, +the system will never accept to include it as part of the theory, +because the guard condition is always verified before saving the proof. + +\begin{coq_example} +Qed. +\end{coq_example} + +\noindent Thus, the user must be careful in the +construction of infinite proofs +with the tactic \verb!Cofix!. Remark that once it has been used +the application of tactics performing automatic proof search in +the environment (like for example \verb!Auto!) +could introduce unguarded recursive calls in the proof. +The command \verb!Guarded! allows to verify +if the guarded condition has been violated +during the construction of the proof. This command can be +applied even if the proof term is not complete. + + + +\begin{coq_example} +Restart. +Cofix. +Auto. +Guarded. +Undo. +Guarded. +\end{coq_example} + +\noindent To finish with this example, let us restart from the +beginning and show how to construct an admissible proof~: + +\begin{coq_example} +Restart. +Cofix. +\end{coq_example} + +%\pagebreak + +\begin{coq_example} +Intros. +Apply eqst. +Trivial. +Simpl. +Apply eqproof. +Qed. +\end{coq_example} + + +\section{Experiments with co-inductive types} + +Some examples involving co-inductive types are available with +the distributed system, in the theories library and in the contributions +of the Lyon site. Here we present a short description of their contents~: +\begin{itemize} +\item Directory \verb!theories/LISTS! : + \begin{itemize} + \item File \verb!Streams.v! : The type of streams and the +extensional equality between streams. + \end{itemize} + +\item Directory \verb!contrib/Lyon/COINDUCTIVES! : + \begin{itemize} + \item Directory \verb!ARITH! : An arithmetic where $\infty$ +is an explicit constant of the language instead of a metatheoretical notion. + \item Directory \verb!STREAM! : + \begin{itemize} + \item File \verb!Examples! : +Several examples of guarded definitions, as well as +of frequent errors in the introduction of a stream. A different +way of defining the extensional equality of two streams, +and the proofs showing that it is equivalent to the one in \verb!theories!. + \item File \verb!Alter.v! : An example showing how +an infinite proof introduced by a guarded definition can be also described +using an operator of co-recursion \cite{Gimenez95b}. + \end{itemize} +\item Directory \verb!PROCESSES! : A proof of the alternating +bit protocol based on Pra\-sad's Calculus of Broadcasting Systems \cite{Prasad93}, +and the verification of an interpreter for this calculus. +See \cite{Gimenez95b} for a complete description about this development. + \end{itemize} +\end{itemize} + +%\end{document} + +% $Id$ diff --git a/doc/RefMan-com.tex b/doc/RefMan-com.tex new file mode 100755 index 000000000..88cf650a1 --- /dev/null +++ b/doc/RefMan-com.tex @@ -0,0 +1,251 @@ +\chapter{The \Coq~commands}\label{Addoc-coqc} +\ttindex{coqtop} +\ttindex{coqc} + +There are two \Coq~commands: + +\bigskip +\begin{tabular}{l@{\quad:\quad}l} + -- {\tt coqtop} & The \Coq\ toplevel (interactive mode) ; \\[1em] + -- {\tt coqc} & The \Coq\ compiler (batch compilation). +\end{tabular} +\bigskip + +The options are (basically) the same for the two commands, and +roughly described below. You can also look at the \verb!man! pages of +\verb!coqtop! and \verb!coqc! for more details. + + +\section{Interactive use ({\tt coqtop})} +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 ran by the +command {\tt coqtop}. This toplevel is based on a Caml toplevel (to +allow the dynamic link of tactics). You can switch to the Caml +toplevel with the command \verb!Drop.!, and come back to the +\Coq~toplevel with the command \verb!Coqtoplevel.go();;!. + +\index{byte-code} +\index{native code} +\label{binary-images} +They are three different binary images of \Coq: the byte-code one, +the native-code one and the full native-code one. When invoking +\verb!coqtop!, the byte-code version of the system is used. The +command \verb!coqtop -opt! runs a native-code version of the +\Coq~system, and the command \verb!coqtop -full! a native-code version +with the implementation code of all the tactics (that is with the code +of the tactics \verb!Linear!, \verb!Ring! and \verb!Omega! which then +can be required by \verb=Require=) and tools (\verb!Extraction! and +\verb!Natural! which again become available through the command +\verb=Require=). Those toplevels are significantly faster than the +byte-code one. Notice that it is no longer possible to access the +Caml toplevel, neither to load tactics. + +The command \verb!coqtop -searchisos! runs the search tool {\sf +Coq\_SearchIsos} (see section~\ref{coqsearchisos}, +page~\pageref{coqsearchisos}) and, as the \Coq~system, can be combined with the +option \verb!-opt!. + +\section{Batch compilation ({\tt coqc})} +The {\tt coqc} command takes a name {\em file} as argument. Then it +looks for a vernacular file named {\em file}{\tt .v}, and tries to +compile it into a {\em file}{\tt .vo} file (See ~\ref{compiled}). +With the \verb!-i! option, it compiles the specification module {\em +file}{\tt .vi}. + +\Warning The name {\em file} must be a regular {\Coq} identifier, as +defined in the section \ref{lexical}. It +must only contain letters, digits or underscores +(\_). Thus it can be \verb+/bar/foo/toto.v+ but not +\verb+/bar/foo/to-to+ . + +Notice that the \verb!-opt! and \verb!-full! options are still +available with \verb!coqc! and allow you to compile \Coq\ files with +an efficient version of the system. + + +\section{Resource file} +\index{Resource file} + +When \Coq\ is launched, with either {\tt coqtop} or {\tt coqc}, the +resource file \verb:$HOME/.coqrc.6.2.4: is loaded, where \verb:$HOME: is +the home directory of the user. If this file is not found, then the +file \verb:$HOME/.coqrc: is searched. You can also specify an +arbitrary name for the resource file (see option \verb:-init-file: +below), or the name of another user to load the resource file of +someone else (see option \verb:-user:). + +This file may contain, for instance, \verb:AddPath: commands to add +directories to the load path of \Coq. You can use the environment +variable \verb:$COQLIB: which refer to the \Coq\ +library. Remember that the +default load path already contains the following directories: +\begin{verbatim} + . + $CAMLP4LIB + $COQLIB/tactics/tcc + $COQLIB/tactics/programs/EXAMPLES + $COQLIB/tactics/programs + $COQLIB/tactics/contrib/polynom + $COQLIB/tactics/contrib/omega + $COQLIB/tactics/contrib/natural + $COQLIB/tactics/contrib/linear + $COQLIB/tactics/contrib/extraction + $COQLIB/tactics/contrib/acdsimpl/simplify_rings + $COQLIB/tactics/contrib/acdsimpl/simplify_naturals + $COQLIB/tactics/contrib/acdsimpl/acd_simpl_def + $COQLIB/tactics/contrib/acdsimpl + $COQLIB/tactics/contrib + $COQLIB/theories/ZARITH + $COQLIB/theories/TREES + $COQLIB/theories/TESTS + $COQLIB/theories/SORTING + $COQLIB/theories/SETS + $COQLIB/theories/RELATIONS/WELLFOUNDED + $COQLIB/theories/RELATIONS + $COQLIB/theories/LOGIC + $COQLIB/theories/LISTS + $COQLIB/theories/INIT + $COQLIB/theories/DEMOS/PROGRAMS + $COQLIB/theories/DEMOS/OMEGA + $COQLIB/theories/DEMOS + $COQLIB/theories/BOOL + $COQLIB/theories/REALS + $COQLIB/theories/ARITH + $COQLIB/tactics + $COQLIB/states +\end{verbatim} + +It is possible to skip the loading of the resource file with the +option \verb:-q:. + +\section{Environment variables} +\label{EnvVariables} +\index{Environment variables} + +There are 3 environment variables used by the \Coq\ system. +\verb:$COQBIN: for the directory where the binaries are, +\verb:$COQLIB: for the directory whrer the standard library is, and +\verb:$COQTOP: for the directory of the sources. The latter is useful +only for developpers that are writing there own tactics using +\texttt{do\_Makeffile} (see \ref{Makefile}). If \verb:$COQBIN: or +\verb:$COQLIB: are not defined, \Coq\ will use the default values +(choosen at installation time). So these variables are useful onlt if +you move the \Coq\ binaries and library after installation. + +\section{Options} +\index{Options of the command line} + +The following command-line options are recognized by the commands {\tt + coqc} and {\tt coqtop}: + +\begin{description} +\item[{\tt -opt}]\ \\ + Run the native-code version of \Coq{} (or {\sf Coq\_SearchIsos} for {\tt +coqtop}). + +\item[{\tt -full}]\ \\ + Run a native-code version of {\Coq} with all tactics. + +\item[{\tt -I} {\em directory}, {\tt -include} {\em directory}]\ \\ + Add {\em directory} to the searched directories when looking for a + file. + +\item[{\tt -R} {\em directory}]\ \\ + Add recursively {\em directory} to the searched directories when looking for + a file. + +\item[{\tt -is} {\em file}, {\tt -inputstate} {\em file}]\ \\ + Cause \Coq~to use the state put in the file {\em file} as its input + state. The default state is {\em tactics.coq}. + Mainly useful to build the standard input state. + +\item[{\tt -nois}]\ \\ + Cause \Coq~to begin with an empty state. Mainly useful to build the + standard input state. + +\item[{\tt -notactics}]\ \\ + Forbid the dynamic loading of tactics, and start on the input state + {\em state.coq}. + +\item[{\tt -init-file} {\em file}]\ \\ + Take {\em file} as resource file, instead of {\tt \$HOME/.coqrc.6.2.4}. + +\item[{\tt -q}]\ \\ + Cause \Coq~not to load the resource file. + +\item[{\tt -user} {\em username}]\ \\ + Take resource file of user {\em username} (that is + \verb+~+{\em username}{\tt /.coqrc.6.2.4}) instead of yours. + +\item[{\tt -load-ml-source} {\em file}]\ \\ + Load the Caml source file {\em file}. + +\item[{\tt -load-ml-object} {\em file}]\ \\ + Load the Caml object file {\em file}. + +\item[{\tt -load-vernac-source} {\em file}]\ \\ + Load \Coq~file {\em file}{\tt .v} + +\item[{\tt -load-vernac-object} {\em file}]\ \\ + Load \Coq~compiled file {\em file}{\tt .vo} + +%\item[{\tt -preload} {\em file}]\ \\ +%Add {\em file}{\tt .vo} to the files to be loaded and opened +%before making the initial state. +% +\item[{\tt -require} {\em file}]\ \\ + Load \Coq~compiled file {\em file}{\tt .vo} and import it ({\tt + Require} {\em file}). + +\item[{\tt -batch}]\ \\ + Batch mode : exit just after arguments parsing. This option is only + used by {\tt coqc}. + +\item[{\tt -debug}]\ \\ + Switch on the debug flag. + +\item[{\tt -emacs}]\ \\ + Tells \Coq\ it is executed under Emacs. + +\item[{\tt -db}]\ \\ + Launch \Coq\ under the Objective Caml debugger (provided that \Coq\ + has been compiled for debugging; see next chapter). + +\item[{\tt -image} {\em file}]\ \\ + This option sets the binary image to be used to be {\em file} + instead of the standard one. Not of general use. + +\item[{\tt -bindir} {\em directory}]\ \\ + It is equivalent to do \texttt{export COQBIN=}{\em directory} + before lauching \Coq. + +\item[{\tt -libdir} {\em file}]\ \\ + It is equivalent to do \texttt{export COQLIB=}{\em directory} + before lauching \Coq. + + +\item[{\tt -where}]\ \\ + Print the \Coq's standard library location and exit. + +\item[{\tt -v}]\ \\ + Print the \Coq's version and exit. + +\item[{\tt -h}, {\tt --help}]\ \\ + Print a short usage and exit. +\end{description} + +{\tt coqtop} owns an additional option: + +\begin{description} +\item[{\tt -searchisos}]\ \\ + Launch the {\sf Coq\_SearchIsos} toplevel + (see section~\ref{coqsearchisos}, page~\pageref{coqsearchisos}). +\end{description} + +See the manual pages for more details. +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/RefMan-cover.tex b/doc/RefMan-cover.tex new file mode 100644 index 000000000..d5a832eed --- /dev/null +++ b/doc/RefMan-cover.tex @@ -0,0 +1,48 @@ +\documentstyle[RRcover]{book} + % L'utilisation du style `french' force le résumé français à + % apparaître en premier. + +\RRtitle{Manuel de r\'ef\'erence du syst\`eme Coq \\ version V6.3} +\RRetitle{The Coq Proof Assistant \\ Reference Manual \\ Version 6.3 +\thanks +{This research was partly supported by ESPRIT Basic Research +Action ``Types'' and by the GDR ``Programmation'' co-financed by MRE-PRC and CNRS.} +} +\RRauthor{Bruno Barras, Samuel Boutin, Cristina Cornes, +Judica\"el Courant, Jean-Christophe Filli\^atre, Eduardo Gim\'enez, +Hugo Herbelin, G\'erard Huet, C\'esar Mu\~noz, Chetan Murthy, +Catherine Parent, Christine Paulin-Mohring, +Amokrane Sa{\"\i}bi, Benjamin Werner} +\authorhead{} +\titlehead{Coq V6.2 Reference Manual} +\RRtheme{2} +\RRprojet{Coq} +\RRNo{0123456789} +\RRdate{May 1997} +%\RRpages{} +\URRocq + +\RRresume{Coq est un syst\`eme permettant le d\'eveloppement et la +v\'erification de preuves formelles dans une logique d'ordre +sup\'erieure incluant un riche langage de d\'efinitions de fonctions. +Ce document constitue le manuel de r\'ef\'erence de la version V6.1 +qui est distribu\'ee par ftp anonyme aux adresses +ftp.inria.fr:/INRIA/Projects/coq/V6.1 et +ftp.ens-lyon.fr:/pub/LIP/COQ/V6.1} + +\RRmotcle{Coq, Syst\`eme d'aide \`a la preuve, Preuves formelles, +Calcul des Constructions Inductives} + + +\RRabstract{Coq is a proof assistant based on a higher-order logic +allowing powerful definitions of functions. +Coq V6.1 is available by anonymous +ftp at ftp.inria.fr:/INRIA/Projects/coq/V6.1 and +ftp.ens-lyon.fr:/pub/LIP/COQ/V6.1} + +\RRkeyword{Coq, Proof Assistant, Formal Proofs, Calculus of Inductives +Constructions} + +\begin{document} +\makeRT +\end{document} diff --git a/doc/RefMan-ext.tex b/doc/RefMan-ext.tex new file mode 100644 index 000000000..7811dfcd5 --- /dev/null +++ b/doc/RefMan-ext.tex @@ -0,0 +1,747 @@ +\chapter{Extensions of {\sf Gallina}} +\label{Gallina-extension}\index{Gallina} + +{\gallina} is the kernel language of {\Coq}. We describe here extensions of +the Gallina's syntax. + +\section{Record types}\comindex{Record} +\label{Record} + +The \verb+Record+ function is a macro allowing +the definition of records as is done in many programming languages. +Its syntax is described on figure \ref{record-syntax}. + +\begin{figure} +\begin{tabular}{|lcl|} +\hline +{\sentence} & ::= & {\record}\\ + & & \\ +{\record} & ::= & {\tt Record} {\ident} {\tt [} {\params} {\tt ] :} {\sort} + \verb.:=. \zeroone{\ident} \verb!{! + \zeroone{\nelist{\field}{;}} + \verb!}! \verb:.:\\ + & & \\ +{\field} & ::= & {\ident} \verb.:. {\term} \\ +\hline +\end{tabular} +\caption{Syntax for the definition of {\tt Record}} +\label{record-syntax} +\end{figure} + +\noindent In the command +``{\tt Record} {\ident} {\tt [} {\params} {\tt ]} \texttt{:} + {\sort} := {\ident$_0$} \verb+{+ + {\ident$_1$} \texttt{:} {\term$_1$}; + \dots + {\ident$_n$} \texttt{:} {\term$_n$} \verb+}+.'', +the identifier {\ident} is the name of the defined record and {\sort} +is its type. The identifier {\ident$_0$} is the name of its +constructor. The identifiers {\ident$_1$}, .., {\ident$_n$} are the +names of its fields and {\term$_1$}, .., {\term$_n$} their respective +types. Records can have parameters. + +\Example +The set of rational numbers may be defined as: +\begin{coq_eval} +Restore State Initial. +\end{coq_eval} +\begin{coq_example} +Record Rat : Set := mkRat { + top : nat; + bottom : nat; + Rat_cond : (gt bottom O) }. +\end{coq_example} + +A field may depend on other fields appearing before it. +For instance in the above example, the field +\verb+Rat_cond+ depends on the field \verb+bottom+. Thus the order of +the fields is important. + +Let us now see the work done by the {\tt Record} macro. +First the macro generates a inductive definition +with just one constructor: + +\medskip +\noindent +{\tt Inductive {\ident} [ {\params} ] : {\sort} := \\ +\mbox{}\hspace{0.4cm} {\ident$_0$} : ({\ident$_1$}:{\term$_1$}) .. +({\ident$_n$}:{\term$_n$})({\ident} {\rm\sl params}).} +\medskip + +To build an object of type {\ident}, one should provide the +constructor {\ident$_0$} with $n$ terms filling the fields of +the record. + +Let us define the rational $1/2$. + +\begin{coq_example*} +Theorem two_is_positive : (gt (S (S O)) O). +Repeat Constructor. +Save. +Definition half := (mkRat (S O) (S (S O)) two_is_positive). +\end{coq_example*} +\begin{coq_example} +Check half. +\end{coq_example} + +The macro generates also, when it is possible, the projection +functions for destructuring an object of type {\ident}. +These projection functions have the same name that the corresponding +field. In our example: + +\begin{coq_example} +Eval Compute in (top half). +Eval Compute in (bottom half). +Eval Compute in (Rat_cond half). +\end{coq_example} +\begin{coq_eval} +Restore State Initial. +\end{coq_eval} + +\begin{Warnings} +\item {\tt Warning: {\ident$_i$} cannot be defined.}\\ + It can happens 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} + \item The name {\ident$_i$} already exists in the environment (see + section \ref{Axiom}). + \item The body of {\ident$_i$} uses a incorrect elimination for + {\ident} (see sections \ref{Fixpoint} and \ref{Caseexpr}). + \item {\tt The projections [ {\rm\sl idents} ] were not defined.}\\ + The body of {\term$_i$} uses the projections {\rm\sl idents} + which are not defined for one of these three reasons listed here. + \end{enumerate} +\end{Warnings} + +\begin{ErrMsgs} +\item \errindex{A record cannot be recursive}\\ + The record name {\ident} appears in the type of its fields. + + During the definition of the one-constructor inductive definition, + all the errors of inductive definitions, as described in section + \ref{gal_Inductive_Definitions}, may occur. +\end{ErrMsgs} + +\begin{Variants} +\item +\noindent +{\tt Record {\ident} [ {\rm\sl params} ] : {\sort} := \verb+{+ \\ +\mbox{}\hspace{0.4cm} {\ident$_1$} : {\term$_1$}; \\ +\mbox{}\hspace{0.4cm} ... \\ +\mbox{}\hspace{0.4cm} {\ident$_n$} : {\term$_n$} \verb+}+.}\\ + +One can omit the constructor name in which case the system will use +the name {\tt Build\_{\ident}}. +\end{Variants} + +\section{Variants and extensions of {\tt Cases}} +\label{ExtensionsOfCases} +\index{Cases@{\tt Cases\ldots of\ldots end}} + +\subsection{ML-style pattern-matching} +\index{ML-like patterns} +\label{Mult-Cases} + +The basic version of \verb+Cases+ allows pattern-matching on simple +patterns. As an extension, multiple and nested patterns are +allowed, as in ML-like languages. + +The extension just acts as a macro that is expanded during parsing +into a sequence of {\tt Cases} on simple patterns. Especially, a +construction defined using the extended {\tt Cases} is printed under +its expanded form. + +The syntax of the extended {\tt Cases} is presented in figure +\ref{ecases-grammar}. +Note the annotation is mandatory when the sequence of equation is +empty. + +\begin{figure}[t] +\begin{tabular}{|rcl|} +\hline +{\nestedpattern} & := & {\ident} \\ + & $|$ & \_ \\ + & $|$ & \texttt{(} {\ident} \nelist{\nestedpattern}{} \texttt{)} \\ + & $|$ & \texttt{(} {\nestedpattern} \texttt{as} {\ident} \texttt{)} \\ + & $|$ & \texttt{(} {\nestedpattern} \texttt{,} {\nestedpattern} \texttt{)} \\ + & $|$ & \texttt{(} {\nestedpattern} \texttt{)} \\ + &&\\ + +{\multpattern} & := & \nelist{nested\_pattern}{} \\ + && \\ + +{\exteqn} & := & {\multpattern} \texttt{=>} {\term} \\ + && \\ + +{\term} & := & + \zeroone{\annotation} \texttt{Cases} \nelist{\term}{} \texttt{of} +\sequence{\exteqn}{$|$} \texttt{end} \\ +\hline +\end{tabular} +\caption{extended Cases syntax.} +\label{ecases-grammar} +\end{figure} + +\SeeAlso chapter \ref{Mult-Cases-full}. + +\subsection{Pattern-matching on boolean values: the {\tt if} expression} +\index{if@{\tt if ... then ... else}} + +For inductive types isomorphic to the boolean types (i.e. two +constructors without arguments), it is possible to use a {\tt if +... then ... else} notation. This enriches the syntax of terms as follows: + +\medskip +\begin{tabular}{rcl} +term & := & \zeroone{\annotation} {\tt if} {\term} {\tt then} {\term} {\tt else} {\term}\\ +\end{tabular} +\medskip + +For instance, the definition + +\begin{coq_example} +Definition not := [b:bool] Cases b of true => false | false => true end. +\end{coq_example} + +can be alternatively written + +\begin{coq_eval} +Reset not. +\end{coq_eval} +\begin{coq_example} +Definition not := [b:bool] if b then false else true. +\end{coq_example} + +\subsection{Irrefutable patterns: the destructuring {\tt let}} +\index{let in@{\tt let ... in}} +\label{Letin} + +Terms in an inductive type having only one constructor, say {\tt foo}, have +necessarily the form \texttt{(foo ...)}. In this case, the {\tt Cases} +construction can be replaced by a {\tt let ... in ...} construction. +This enriches the syntax of terms as follows: + +\medskip +\begin{tabular}{rcl} + & $|$ & \zeroone{\annotation} {\tt let (} \nelist{\ident}{,} {\tt ) =} {\term} {\tt in} {\term} \\ +\end{tabular} +\medskip + +For instance, the definition + +\begin{coq_example} +Definition fst := [A,B:Set][H:A*B] Cases H of (pair x y) => x end. +\end{coq_example} + +can be alternatively written + +\begin{coq_eval} +Reset fst. +\end{coq_eval} +\begin{coq_example} +Definition fst := [A,B:Set][p:A*B] let (x,_) = p in x. +\end{coq_example} + +The pretty-printing of a definition by cases on a irrefutable pattern +can either be done using {\tt Cases} or the {\tt let} +construction (see section \ref{printing-options}). + +\subsection{Options for pretty-printing of {\tt Cases}} +\label{printing-options} + +There are three options controlling the pretty-printing of {\tt Cases} +expressions. + +\subsubsection{Printing of wildcard pattern} +\comindex{Set Printing Wildcard} +\comindex{Unset Printing Wildcard} +\comindex{Print Printing Wildcard} + +Some variables in a pattern may not occur in the right-hand side of +the pattern-matching clause. There are options to control the +display of these variables. + +\subsubsection{\tt Set Printing Wildcard.} + The variables having no occurrences +in the right-hand side of the pattern-matching clause are just +printed using the wildcard symbol ``{\tt \_}''. + +\subsubsection{\tt Unset Printing Wildcard.} +The variables, even useless, are printed using their usual name. But some +non dependent variables have no name. These ones are still printed +using a ``{\tt \_}''. + +\subsubsection{\tt Print Printing Wildcard.} +This tells if the wildcard +printing mode is on or off. The default is to print wildcard for +useless variables. + +\subsubsection{Printing of the elimination predicate} +\comindex{Set Printing Synth} +\comindex{Unset Printing Synth} +\comindex{Print Printing Synth} + +In most of the cases, the type of the result of a matched term is +mechanically synthesizable. Especially, if the result type does not +depend of the matched term. + +\subsubsection{\tt Set Printing Synth.} +The result type is not printed +when it is easily synthesizable. + +\subsubsection{\tt Unset Printing Synth.} +This forces the result type to be always printed (and then between +angle brackets). + +\subsubsection{\tt Print Printing Synth.} +This tells if the non-printing +of synthesizable types is on or off. The default is to not print +synthesizable types. + +\subsubsection{Printing matching on irrefutable pattern} +\comindex{Add Printing Let {\ident}} +\comindex{Remove Printing Let {\ident}} +\comindex{Test Printing Let {\ident}} +\comindex{Print Printing Let} + +If an inductive type has just one constructor, +pattern-matching can be written using {\tt let} ... {\tt =} +... {\tt in}~... + +\subsubsection{\tt Add Printing Let {\ident}.} +This adds {\ident} to the list +of inductive types for which pattern-matching is written using a {\tt +let} expression. + +\subsubsection{\tt Remove Printing Let {\ident}.} +This removes {\ident} from this list. + +\subsubsection{\tt Test Printing Let {\ident}.} +This tells if {\ident} belongs +to the list. + +\subsubsection{\tt Print Printing Let.} +This prints the list of inductive types +for which pattern-matching is written using a {\tt +let} expression. + +The table of inductive types for which pattern-matching is written +using a {\tt let} expression is managed synchronously. This means that +it is sensible to the command {\tt Reset}. + + +\subsubsection{Printing matching on booleans} +\comindex{Add Printing If {\ident}} +\comindex{Remove Printing If {\ident}} +\comindex{Test Printing If {\ident}} +\comindex{Print Printing If} + +If an inductive type is isomorphic to the boolean type, +pattern-matching can be written using {\tt if} ... {\tt then} +... {\tt else} ... + +\subsubsection{\tt Add Printing If {\ident}.} +This adds {\ident} to the list +of inductive types for which pattern-matching is written using an {\tt +if} expression. + +\subsubsection{\tt Remove Printing If {\ident}.} +This removes {\ident} from this list. + +\subsubsection{\tt Test Printing If {\ident}.} +This tells if {\ident} belongs +to the list. + +\subsubsection{\tt Print Printing If.} +This prints the list of inductive types +for which pattern-matching is written using an {\tt +if} expression. + +The table of inductive types for which pattern-matching is written +using an {\tt if} expression is managed synchronously. This means that +it is sensible to the command {\tt Reset}. + +\subsubsection{Example} + +This example emphasizes what the printing options offer. + +\begin{coq_example} +Test Printing Let prod. +Print fst. +Remove Printing Let prod. +Unset Printing Synth. +Unset Printing Wildcard. +Print snd. +\end{coq_example} + +\subsection{Still not dead old notations} + +The following variant of {\tt Cases} is inherited from older version +of {\Coq}. + +\medskip +\begin{tabular}{lcl} +{\term} & ::= & {\annotation} {\tt Match} {\term} {\tt with} {\terms} {\tt end}\\ +\end{tabular} +\medskip + +This syntax is a macro generating a combination of {\tt Cases} with {\tt +Fix} implementing a combinator for primitive recursion equivalent to +the {\tt Match} construction of \Coq\ V5.8. It is provided only for +sake of compatibility with \Coq\ V5.8. It is recommended to avoid it. +(see section~\ref{Matchexpr}). + +There is also a notation \texttt{Case} that is the +ancestor of \texttt{Cases}. Again, it is still in the code for +compatibility with old versions but the user should not use it. + +\section{Forced type} + +In some cases, one want to assign a particular type to a term. The +syntax to force the type of a term is the following: + +\medskip +\begin{tabular}{lcl} +{\term} & ::= & {\tt (} {\term} {\tt ::} {\term} {\tt )}\\ +\end{tabular} +\medskip + +It forces the first term to be of type the second term. The +type must be compatible with +the term. More precisely it must be either a type convertible to +the automatically inferred type (see chapter \ref{Cic}) or a type +coercible to it, (see \ref{Coercions}). When the type of a +whole expression is forced, it is usually not necessary to give the types of +the variables involved in the term. + +Example: + +\begin{coq_example} +Definition ID := (X:Set) X -> X. +Definition id := (([X][x]x) :: ID). +Check id. +\end{coq_example} + +\section{Local definitions} +\index{let in@{\tt let ... in}} +In addition to the destructuring {\tt let} (see section +\ref{Letin}), there is a possibility to define local terms inside a +bigger term. +There are currently two equivalent syntaxes for that: + +\medskip +\begin{tabular}{lcl} +{\term} & ::= & {\tt let} {\ident} {\tt =} {\term} {\tt in} {\term}\\ + & $|$ & {\tt [} {\ident} {\tt =} {\term} {\tt ]} {\term} +\end{tabular} +\medskip + +\section{Section mechanism}\index{Sections}\label{Section} +The sectioning mechanism allows to organize a proof in structured +sections. Then local declarations become available (see section +\ref{Simpl-definitions}). + +\subsection{\tt Section {\ident}}\comindex{Section} +This command is used to open a section named {\ident}. + + +\begin{Variants} +\comindex{Chapter} +\item{\tt Chapter {\ident}}\\ + Same as {\tt Section {\ident}} +\end{Variants} + +\subsection{\tt End {\ident}}\comindex{End} +This command closes the section named {\ident}. When a section is +closed, all local declarations are discharged. This means that all +global objects defined in the section are {\it closed} (in the sense +of $\lambda$-calculus) with as many abstractions as there were local +declarations in the section explicitly occurring in the term. A local +object in the section is not exported and its value will be +substituted in the other definitions. + +Here is an example : +\begin{coq_example} +Section s1. +Variables x,y : nat. +Local y' := y. +Definition x' := (S x). +Print x'. +End s1. +Print x'. +\end{coq_example} +Note the difference between the value of {\tt x'} inside section {\tt + s1} and outside. + +\begin{ErrMsgs} +\item \errindex{Section {\ident} does not exist (or is already closed)} +\item \errindex{Section {\ident} is not the innermost section} +\end{ErrMsgs} + +\begin{Remarks} +\item Most commands, like {\tt Hint \ident} or {\tt Syntactic + Definition} which appear inside a section are cancelled when the +section is closed. +\item Usually, all identifiers must be distinct. +However, a name already used in a closed section (see \ref{Section}) +can be reused. In this case, the old name is no longer accessible. +\item A module implicitly open a section. Be careful not to name a +module with an identifier already used in the module (see \ref{compiled}). +\end{Remarks} + +\section{Implicit arguments}\index{implicit arguments} + +The {\Coq} system allows to skip during a function application certain +arguments that can be automatically inferred from the other +arguments. Such arguments are called {\em implicit}. Typical implicit +arguments are the type arguments in polymorphic functions. + +The user can force a subterm to be guessed by replacing it by +{\tt ?}. If possible, the correct subterm will be automatically generated. + +\ErrMsg +\begin{enumerate} +\item \errindex{There is an unknown subterm I cannot solve} \\ + {\Coq} was not able to deduce an instantiation of a ``?''. +\end{enumerate} + +In addition, there are two ways to systematically avoid to write +``{\tt ?}'' where a term can be automatically inferred. + +The first mode is automatic. Switching to this mode forces some +easy-to-infer subterms to always be implicit. +The command to use the second mode is {\tt Syntactic +Definition}. + +\subsection{Auto-detection of implicit arguments} +\label{Auto-implicit} + +There is an automatic mode to declare as implicit some arguments of +constants and variables which have a functional type. In this mode, +to every declared object (even inductive types and theirs constructors) is +associated the list of the positions of its implicit arguments. These +implicit arguments correspond to the arguments which can be deduced +from the following ones. Thus when one applies these functions to +arguments, one can omit the implicit ones. They are then automatically +replaced by symbols ``?'', to be inferred by the mechanism of +synthesis of implicit arguments. + +\subsubsection{\tt Implicit Arguments {\switch}.} +\comindex{Implicit Arguments} +\label{Implicit Arguments} + +If {\switch} is {\tt On} then the command switches on the automatic +mode. If {\switch} is {\tt Off} then the command switches off the +automatic mode. The mode {\tt Off} is the default mode. + +The computation of implicit arguments takes account of the +unfolding of constants. For instance, the variable {\tt p} below has +a type {\tt (Transitivity R)} which is reducible to {\tt (x,y:U)(R x +y) -> (z:U)(R y z) -> (R x z)}. As the variables {\tt x}, {\tt y} and +{\tt z} appear in the body of the type, they are said implicit; they +correspond respectively to the positions {\tt 1}, {\tt 2} and {\tt 4}. + +\begin{coq_example*} +Implicit Arguments On. +Variable X : Type. +Definition Relation := X -> X -> Prop. +Definition Transitivity := [R:Relation] + (x,y:X)(R x y) -> (z:X)(R y z) -> (R x z). +Variables R:Relation; p:(Transitivity R). +\end{coq_example*} +\begin{coq_example} +Print p. +\end{coq_example} +\begin{coq_example*} +Variables a,b,c:X; r1:(R a b); r2:(R b c). +\end{coq_example*} +\begin{coq_example} +Check (p r1 r2). +\end{coq_example} + +\subsubsection{Explicit Applications} + +The mechanism of synthesis of implicit arguments is not complete, so +we have sometimes to give explicitly certain implicit arguments of an +application. The syntax is {\tt $i$!}{\term} where $i$ is the position +of an implicit argument and {\term} is its corresponding explicit +term. The number $i$ is called {\em explicitation number}. We can +also give all the arguments of an application, we have then to write +{\tt (!{\ident}~{\term}$_1$..{\term}$_n$)}. + +\ErrMsg +\begin{enumerate} +\item \errindex{Bad explicitation number} +\end{enumerate} + +\Example + +\begin{coq_example} +Check (p r1 4!c). +Check (!p a b r1 c r2). +\end{coq_example} + +\subsubsection{Implicit Arguments and Pretty-Printing} + +The basic pretty-printing rules hide the implicit arguments of an +application. However an implicit argument {\term} of an application +which is not followed by any explicit argument is printed as follows +$i!${\term} where $i$ is its position. + +\subsection{User-defined implicit arguments: {\tt Syntactic definition}} +\comindex{Syntactic Definition} +\label{Syntactic-Definition} + +The syntactic definitions define syntactic constants, i.e. give a name +to a term possibly untyped but syntactically correct. Their syntax +is: + +\begin{center} +\verb+Syntactic Definition+ $name$ \verb+:=+ $term$ \verb+.+ \\ +\end{center} + +Syntactic definitions behave like macros: every occurrence of a +syntactic constant in an expression is immediately replaced by its +body. + +Let us extend our functional language with the definition of the +identity function: + +\begin{coq_eval} +Implicit Arguments Off. +Reset Initial. +\end{coq_eval} +\begin{coq_example} +Definition explicit_id := [A:Set][a:A]a. +\end{coq_example} + +\index{questionmark@{\texttt{?}}} +We declare also a syntactic definition {\tt id}: + +\begin{coq_example} +Syntactic Definition id := (explicit_id ?). +\end{coq_example} + +The term {\tt (explicit\_id ?)} is untyped since the implicit +arguments cannot be synthesized. There is no type check during this +definition. Let us see what happens when we use a syntactic constant +in an expression like in the following example. + +\begin{coq_example} +Check (id O). +\end{coq_example} + +\noindent First the syntactic constant {\tt id} is replaced by its +body {\tt (explicit\_id ?)} in the expression. Then the resulting +expression is evaluated by the typechecker, which fills in +``\verb+?+'' place-holders. + +The standard usage of syntactic definitions is to give names to terms +applied to implicit arguments ``\verb+?+''. In this case, a special +command is provided: + +\begin{center} +\verb+Syntactic Definition+ $name$ \verb+:=+ $term$ \verb+|+ $n$ \verb+.+ \\ +\end{center} + +\noindent The body of the syntactic constant is $term$ applied to $n$ +place-holders ``\verb+?+''. + +We can define a new syntactic definition {\tt id1} for {\tt + explicit\_id} using this command. We changed the name of the +syntactic constant in order to avoid a name conflict with {\tt id}. + +\begin{coq_example} +Syntactic Definition id1 := explicit_id | 1. +\end{coq_example} + +The new syntactic constant {\tt id1} has the same behavior as {\tt + id}: + +\begin{coq_example} +Check (id1 O). +\end{coq_example} + + +\begin{Warnings} +\item Syntactic constants defined inside a section are no longer + available after closing the section. +\item You cannot see the body of a syntactic constant with a {\tt + Print} command. +\end{Warnings} + +\section{Implicit Coercions} +\label{Coercions}\index{Coercions} + +Coercions can be used to implicitly inject terms from one ``class'' in +which they reside into another one. A {\em class} is either a sort +(denoted by the keyword SORTCLASS), a product type (denoted by the +keyword FUNCLASS) or an inductive type (denoted by its name). + +Then the user is able to apply an +object that is not a function, but can be coerced to a function, and +more generally to consider that a term of type A is of type B provided +that there is a declared coercion between A and B. + +\subsection{\tt Class {\ident}.}\comindex{Class} +Declares the name {\ident} as a new class. + +\begin{Variant} +\item {\tt Class Local {\ident}.} \\ +Declares the name {\ident} as a new local class to the current section. +\end{Variant} + +\subsection{\tt Coercion {\ident} : {\ident$_1$} >-> {\ident$_2$}.} +\comindex{Coercion} + +Declares the name {\ident} as a coercion between {\ident$_1$} and +{\ident$_2$}. The classes {\ident$_1$} and {\ident$_2$} are first +declared if necessary. + +\begin{Variants} +\item {\tt Coercion Local {\ident} : {\ident$_1$} >-> {\ident$_2$}.}\comindex{Coercion Local}\\ +Declares the name {\ident} as a coercion local to the current section. + +\item {\tt Identity Coercion {\ident}:{\ident$_1$} >-> + {\ident$_2$}.}\comindex{Identity Coercion}\\ +Coerce an inductive type to a subtype of it. + +\item {\tt Identity Coercion Local {\ident}:{\ident$_1$} >-> {\ident$_2$}.} \\ +Idem but locally to the current section. + +\item {\tt Coercion {\ident} := {\term}}\comindex{Coercion}\\ + This defines {\ident} just like \texttt{Definition {\ident} := + {\term}}, and then declares {\ident} as a coercion between it + source and its target. + +\item {\tt Coercion {\ident} := {\term} : {\type}}\\ + This defines {\ident} just like + \texttt{Definition {\ident} : {\type} := {\term}}, and then + declares {\ident} as a coercion between it source and its target. + +\item {\tt Coercion Local {\ident} := {\term}}\comindex{Local Coercion}\\ + This defines {\ident} just like \texttt{Local {\ident} := + {\term}}, and then declares {\ident} as a coercion between it + source and its target. + +\end{Variants} + +\subsection{Displaying available coercions} + +\subsubsection{\tt Print Classes.}\comindex{Print Classes} +Print the list of declared classes in the current context. + +\subsubsection{\tt Print Coercions.}\comindex{Print Coercions} +Print the list of declared coercions in the current context. + +\subsubsection{\tt Print Graph.}\comindex{Print Graph} +Print the list of valid path coercions in the current context. + +\SeeAlso the technical chapter \ref{Coercions-full} on coercions. + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/RefMan-gal.tex b/doc/RefMan-gal.tex new file mode 100644 index 000000000..ac7182630 --- /dev/null +++ b/doc/RefMan-gal.tex @@ -0,0 +1,1209 @@ +\chapter{The {\sf Gallina} specification language} +\label{Gallina}\index{Gallina} + +This chapter describes \gallina, the specification language of Coq. +It allows to develop mathematical theories and to prove specifications +of programs. The theories are built from axioms, hypotheses, +parameters, lemmas, theorems and definitions of constants, functions, +predicates and sets. The syntax of logical objects involved in +theories is described in section \ref{term}. The language of +commands, called {\em The Vernacular} is described in section +\ref{Vernacular}. + +In Coq, logical objects are typed to ensure their logical +correctness. The rules implemented by the typing algorithm are described in +chapter \ref{Cic}. + +\subsection*{About the grammars in the manual} + +Grammars are presented in Backus-Naur form (BNF). Terminal symbols are +set in {\tt typewriter font}. In addition, there are special +notations for regular expressions. + +An expression enclosed in square brackets \zeroone{\ldots} means at +most one occurrence of this expression (this corresponds to an +optional component). + +The notation ``\nelist{\gensymbol}{sep}'' stands for a non empty +sequence of expressions parsed by the ``{\gensymbol}'' entry and +separated by the literal ``{\tt sep}''\footnote{This is similar to the +expression ``{\gensymbol} $\{$ {\tt sep} {\gensymbol} $\}$'' in +standard BNF, or``{\gensymbol} $($ {\tt sep} {\gensymbol} $)$*'' in +the syntax of regular expressions.}. + +Similarly, the notation ``\nelist{\gensymbol}{}'' stands for a non +empty sequence of expressions parsed by the ``{\gensymbol}'' entry, +without any separator between. + +At the end, the notation ``\sequence{\gensymbol}{\tt sep}'' stands for a +possibly empty sequence of expressions parsed by the ``{\gensymbol}'' entry, +separated by the literal ``{\tt sep}''. + +\section{Lexical conventions} +\label{lexical}\index{Lexical conventions} + +\paragraph{Blanks} +Space, newline and horizontal tabulation are considered as blanks. +Blanks are ignored but they separate tokens. + +\paragraph{Comments} + +Comments in {\Coq} are enclosed between {\tt (*} and {\tt + *)}\index{Comments}, and can be nested. Comments are treated as +blanks. + +\paragraph{Identifiers} + +Identifiers, written {\ident}, are sequences of letters, digits, +\verb!_!, \verb!$! %$ +and \verb!'!, that do not start with a digit or \verb!'!. That is, +they are recognized by the following lexical class: + +\index{ident@\ident} +\begin{center} +\begin{tabular}{rcl} +{\firstletter} & ::= & \ml{a..z}\op\ml{A..Z}\op\ml{\_}\op\ml{\$} \\ +{\subsequentletter} & ::= & \ml{a..z}\op\ml{A..Z}\op\ml{0..9}\op\ml{\_}\op\ml{\$}\op\ml{'} \\ +{\ident} & ::= & {\firstletter}\sequencewithoutblank{\subsequentletter}{}\\ +\end{tabular} +\end{center} +Identifiers can contain at most 80 characters, and all characters are +meaningful. In particular, identifiers are case-sensitive. + +\paragraph{Natural numbers and integers} +Numerals are sequences of digits. Integers are numerals optionally preceded by a minus sign. + +\index{num@{\num}} +\begin{center} +\begin{tabular}{r@{\quad::=\quad}l} +{\digit} & \ml{0..9} \\ +{\num} & \nelistwithoutblank{\digit}{} \\ +{\integer} & \zeroone{\ml{-}}{\num} \\ +\end{tabular} +\end{center} + +\paragraph{Strings} +Strings are delimited by \verb!"! (double quote), and enclose a +sequence of any characters different from \verb!"! and \verb!\!, or +one of the following sequences +\begin{center} +\begin{tabular}{|l|l|} +\hline +Sequence & Character denoted \\ +\hline +\verb"\\" & backslash (\verb"\") \\ +\verb'\"' & double quote (\verb'"') \\ +\verb"\n" & newline (LF) \\ +\verb"\r" & return (CR) \\ +\verb"\t" & horizontal tabulation (TAB) \\ +\verb"\b" & backspace (BS) \\ +\verb"\"$ddd$ & the character with ASCII code $ddd$ in decimal \\ +\hline +\end{tabular} +\end{center} +Strings can be split on several lines using a backslash (\verb!\!) at +the end of each line, just before the newline. For instance, + +\begin{flushleft} +\begin{small} +\begin{verbatim} +AddPath "$COQLIB/\ +contrib/Rocq/LAMBDA". +\end{verbatim} +\end{small} +\end{flushleft} + +is correctly parsed, and equivalent to + +\begin{coq_example*} +AddPath "$COQLIB/contrib/Rocq/LAMBDA". +\end{coq_example*} + +\paragraph{Keywords} +The following identifiers are reserved keywords, and cannot be +employed otherwise: +\begin{center} +\begin{tabular}{lllll} +\verb!as! & +\verb!end! & +\verb!in! & +\verb!of! & +\verb!using! \\ +\verb!with! & +\verb!Axiom! & +\verb!Cases! & +\verb!CoFixpoint! & +\verb!CoInductive!\\ +\verb!Compile! & +\verb!Definition! & +\verb!Fixpoint! & +\verb!Grammar! & +\verb!Hypothesis! \\ +\verb!Inductive! & +\verb!Load! & +%%\verb!Orelse! & +\verb!Parameter! & +\verb!Proof! & +\verb!Prop! \\ +\verb!Qed! & +\verb!Quit! & +\verb!Set! & +\verb!Syntax! & +\verb!Theorem! \\ +\verb!Type! & +\verb!Variable! & & & +\end{tabular} +\end{center} + +Although they are not considered as keywords, it is not advised to use +words of the following list as identifiers: +\begin{center} +\begin{tabular}{lllll} +\verb!Add! & +\verb!AddPath! & +\verb!Abort! & +\verb!Abstraction!& +\verb!All! \\ +\verb!Begin! & +\verb!Cd! & +\verb!Chapter! & +\verb!Check! & +\verb!Compute! \\ +% \verb!Conjectures! \\ que dans Show Conjectures sans conflit avec ident +\verb!Defined! & +\verb!DelPath! & +\verb!Drop! & +\verb!End! & +\verb!Eval! \\ +% \verb!Explain! n'est pas documente +\verb!Extraction! & +\verb!Fact! & +\verb!Focus! & +% \verb!for! n'intervient que pour Scheme ... Induction ... sans conflit +% \verb!Go! n'est pas documente et semble peu robuste aux erreurs +\verb!Goal! & +\verb!Guarded! \\ +\verb!Hint! & +\verb!Immediate! & +\verb!Induction! & +\verb!Infix! & +\verb!Inspect! \\ +\verb!Lemma! & +\verb!Let! & +\verb!LoadPath! & +\verb!Local! & +\verb!Minimality! \\ +\verb!ML! & +\verb!Module! & +\verb!Modules! & +\verb!Mutual! & +% \verb!Node! que dans Show Node sans conflit avec ident +\verb!Opaque! \\ +\verb!Parameters! & +\verb!Print! & +\verb!Pwd! & +\verb!Remark! & +\verb!Remove! \\ +\verb!Require! & +\verb!Reset! & +\verb!Restart! & +\verb!Restore! & +\verb!Resume! \\ +\verb!Save! & +\verb!Scheme! & +% \verb!Script! que dans Show Script sans conflit avec ident +\verb!Search! & +\verb!Section! & +\verb!Show! \\ +\verb!Silent! & +\verb!State! & +\verb!States! & +\verb!Suspend! & +\verb!Syntactic! \\ +\verb!Test! & +\verb!Transparent!& +% \verb!Tree! que dans Show Tree et Explain Proof Tree sans conflit avec id +\verb!Undo! & +\verb!Unset! & +\verb!Unfocus! \\ +\verb!Variables! & +\verb!Write! & & & +\end{tabular} +\end{center} + +\paragraph{Special tokens} +The following sequences of characters are special tokens: +\begin{center} +\begin{tabular}{lllllll} +\verb!|! & +\verb!:! & +\verb!:=! & +\verb!=! & +\verb!>! & +\verb!>>! & +\verb!<>! \\ +\verb!<<! & +\verb!<! & +\verb!->! & +\verb!;! & +\verb!#! & +\verb!*! & +\verb!,! \\ +\verb!?! & +\verb!@! & +\verb!::! & +\verb!/! & +\verb!<-! & +\verb!=>! & +\end{tabular} +\end{center} + +Lexical ambiguities are resolved according to the ``longest match'' +rule: when a sequence of non alphanumerical characters can be decomposed +into several different ways, then the first token is the longest +possible one (among all tokens defined at this moment), and so on. + +\section{Terms}\label{term}\index{Terms} +\subsection{Syntax of terms} + +Figure \ref{term-syntax} describes the basic set of terms which form +the {\em Calculus +of Inductive Constructions} (also called \CIC). The formal +presentation of {\CIC} is given in chapter \ref{Cic}. Extensions of +this syntax are given in chapter +\ref{Gallina-extension}. How to customize the syntax is described in +chapter \ref{Addoc-syntax}. + +\begin{figure}[htb] +\begin{tabular}{|lcl|} +\hline +{\term} & ::= & \ident\\ + & $|$ & \sort \\ + & $|$ & {\term} {\tt ->} {\term} \\ + & $|$ & {\tt (} {\nelist{\typedidents}{;}} {\tt )} {\term}\\ + & $|$ & {\tt [} {\nelist{\idents}{;}} {\tt ]} {\term}\\ + & $|$ & {\tt (} \nelist{\term}{} {\tt )}\\ + & $|$ & {\tt \zeroone{\annotation}} {\tt Cases} {\term} {\tt of} + \sequence{\eqn}{|} {\tt end}\\ + & $|$ & {\tt Fix} {\ident} \verb.{. \nelist{\fixpointbody}{with} \verb.}.\\ + & $|$ & {\tt CoFix} {\ident} \verb.{. \nelist{\cofixpointbody}{with} \verb.}.\\ + & & \\ +{\sort} & ::= & {\tt Prop} \\ + & $|$ & {\tt Set} \\ + & $|$ & {\tt Type} \\ + & & \\ +{\annotation} & ::= & \verb!<! {\term} \verb!>!\\ + & & \\ +{\typedidents} & ::= & \nelist{\ident}{,} {\tt :} {\term}\\ +{\idents} & ::= & \nelist{\ident}{,} \zeroone{{\tt :} {\term}}\\ + & & \\ +{\fixpointbody} & ::= & {\ident} {\tt [} \nelist{\typedidents}{;} {\tt ]}\verb.:. + {\term} \verb.:=. {\term} \\ +{\cofixpointbody} & ::= & {\ident} \verb.:. + {\term} \verb.:=. {\term} \\ + & &\\ +{\simplepattern} & ::= & {\ident} \\ + & $|$ & \verb!(! \nelist{\ident}{} \verb!)! \\ +{\eqn} & ::= & {\simplepattern} ~\verb!=>! ~\term \\ +\hline +\end{tabular} +\caption{Syntax of terms} +\label{term-syntax} +\index{term@{\term}} +\index{sort@{\sort}} +\end{figure} + +%%%%%%% +\subsection{Identifiers} + +Identifiers denotes either {\em variables}, {\em constants}, +{\em inductive types} or {\em constructors of inductive types}. + +\subsection{Sorts}\index{Sorts} +\index{Type@{\Type}} +\index{Set@{\Set}} +\index{Prop@{\Prop}} +\index{Sorts} +\label{Gallina-sorts} + +There are three sorts \Set, \Prop\ and \Type. + +\begin{itemize} +\item \Prop\ is the universe of {\em logical propositions}. +The logical propositions themselves are typing the proofs. +We denote propositions by {\form}. This constitutes a semantic +subclass of the syntactic class {\term}. +\index{form@{\form}} +\item \Set\ is is the universe of {\em program +types} or {\em specifications}. +The specifications themselves are typing the programs. +We denote specifications by {\specif}. This constitutes a semantic +subclass of the syntactic class {\term}. +\index{specif@{\specif}} +\item {\Type} is the type of {\Set} and {\Prop} +\end{itemize} + +\noindent More on sorts can be found in section \ref{Sorts}. + +\subsection{Types} + +{\Coq} terms are typed. {\Coq} types are recognized by the same +syntactic class as {\term}. We denote by {\type} the semantic subclass +of types inside the syntactic class {\term}. +\index{type@{\type}} + +\subsection{Abstractions} +\index{abstractions} + +The expression ``{\tt [} {\ident} {\tt :} \type {\tt ]} +{\term}'' denotes the {\em abstraction} of the variable {\ident} +of type {\type}, over the term {\term}. + +One can abstract several variables successively: +the notation {\tt [} {\ident$_{1}$} {\tt ,} {\ldots} {\tt ,} +{\ident$_{n}$} {\tt :} \type {\tt ]} {\term} stands for +{\tt [} {\ident$_{1}$} {\tt :} \type {\tt ](} {\ldots} +{\tt ([} {\ident$_{n}$} {\tt :} \type {\tt ]} {\term} {\tt )} +\ldots {\tt )} and the notation {\tt [} {\typedidents$_{1}$} {\tt ;} +{\ldots} {\tt ;} {\typedidents$_{m}$} {\tt ]} {\term} is a shorthand +for {\tt [}~{\typedidents$_{1}$} {\tt ](} {\ldots} {\tt ([} +{\typedidents$_{m}$} {\tt ]} {\term} {\tt )}\\ {\tt [} {\ident$_{1}$} +{\tt ,} {\ldots} {\tt ,} {\ident$_{n}$} {\tt :} \type {\tt ]} {\term}. + +\medskip +\Rem The types of variables may be omitted in an +abstraction when they can be synthetized by the system. + +\subsection{Products} +\index{products} + +The expression ``{\tt (}~{\ident} {\tt :} \type {\tt )} +{\term}'' denotes the {\em product} of the variable {\ident} +of type {\type}, over the term {\term}. + +Similarly, the expression {\tt (} {\ident$_{1}$} {\tt ,} {\ldots} {\tt +,} {\ident$_{n}$} {\tt :} \type {\tt )} {\term} is equivalent to {\tt +(} {\ident$_{1}$} {\tt :} \type {\tt )(} {\ldots} {\tt ((} +{\ident$_{n}$} {\tt :} \type {\tt )} {\term} {\tt )} \ldots {\tt )} +and the expression {\tt (} {\typedidents$_{1}$} {\tt ;} {\ldots} {\tt +;} {\typedidents$_{m}$} {\tt )} {\term} is a equivalent to {\tt +(}~{\typedidents$_{1}$} {\tt )(} {\ldots} {\tt ((} +{\typedidents$_{m}$} {\tt )} {\term} {\tt )} \ldots {\tt )} + +\subsection{Applications} +\index{applications} + +{\tt (}\term$_0$ \term$_1${\tt)} denotes the application of + term \term$_0$ to \term$_1$. + +The expression {\tt (}\term$_0$ \term$_1$ ... \term$_n${\tt)} +denotes the application of the term \term$_0$ to the arguments +\term$_1$ ... then \term$_n$. It is equivalent to {\tt (} {\ldots} +{\tt (} {\term$_0$} {\term$_1$} {\tt )} {\ldots} {\term$_n$} {\tt )}: +associativity is to the left. + +\subsection{Definition by case analysis} +\index{Cases@{\tt Cases\ldots of\ldots end}} + +In a simple pattern \verb!(! \nelist{\ident}{} \verb!)!, the first {\ident} +is intended to be a constructor. + +The expression {\tt \zeroone{\annotation}} {\tt Cases} {\term$_0$} {\tt of} +{\pattern$_1$} {\tt =>} {\term$_1$} {\tt $|$} {\ldots} {\tt $|$} +{\pattern$_n$} {\tt =>} {\term$_n$} {\tt end}, denotes a +{\em pattern-matching} over the term {\term$_0$} (expected to be of an +inductive type). + +The {\annotation} is the resulting type of the whole {\tt Cases} +expression. Most of the time, when this type is the same as the +types of all the {\term$_i$}, the annotation is not needed\footnote{except +if no equation is given, to match the term in an empty type, e.g. the +type \texttt{False}}. The annotation has to be given when the +resulting type of the whole {\tt Cases} depends on the actual {\term$_0$} +matched. + + +\subsection{Recursive functions} +\index{Fix@{Fix \ident$_i$\{\dots\}}} + +The expression {\tt Fix} {\ident$_i$} \verb.{. \ident$_1$ {\tt [} +\binders$_1$ {\tt ] :} {\type$_1$} \texttt{:=} \term$_1$ +{\tt with} {\ldots} +{\tt with} \ident$_n$ {\tt [} \binders$_n$~{\tt{]} :} {\type$_n$} +\texttt{:=} \term$_n$ \verb.}. denotes +the $i$th component of a block of functions defined by mutual +well-founded recursion. + +The expression {\tt CoFix} {\ident$_i$} \verb.{. \ident$_1$ +{\tt :} {\type$_1$} {\tt with} {\ldots} {\tt with} +\ident$_n$ {\tt [} \binders$_n$ {\tt ] :} {\type$_n$} \verb.}. denotes +the $i$th component of a block of terms defined by a mutual guarded recursion. + +\section{\em The Vernacular} +\label{Vernacular} + +Figure \ref{sentences-syntax} describes {\em The Vernacular} which is the +language of commands of \gallina. A sentence of the vernacular +language, like in many natural languages, begins with a capital letter +and ends with a dot. +\begin{figure} +\label{sentences-syntax} +\begin{tabular}{|lcl|} +\hline +{\sentence} & ::= & {\declaration} \\ + & $|$ & {\definition} \\ + & $|$ & {\statement} \\ + & $|$ & {\inductive} \\ + & $|$ & {\fixpoint} \\ + & $|$ & {\statement} ~~ {\proof} \\ + & & \\ +{\params} & ::= & \nelist{\typedidents}{;} \\ + & & \\ +{\declaration} & ::= & + {\tt Axiom} {\ident} \verb.:. {\term} \verb:.: \\ + & $|$ & {\declarationkeyword} {\params} \verb:.: \\ + & & \\ +{\declarationkeyword} & ::= & +{\tt Parameter} $|$ {\tt Parameters} \\ + & $|$ & {\tt Variable} $|$ {\tt Variables} \\ + & $|$ & {\tt Hypothesis} $|$ {\tt Hypotheses}\\ + & & \\ + +{\definition} & ::= & + {\tt Definition} {\ident} \zeroone{{\tt :} {\term}} \verb.:=. {\term} \verb:.: \\ + & $|$ & {\tt Local} {\ident} \zeroone{{\tt :} {\term}} \verb.:=. {\term} \verb:.: \\ + & & \\ + +{\inductive} & ::= & + \zeroone{\texttt{Mutual}} {\tt Inductive} \nelist{\inductivebody}{with} + \verb:.: \\ + & $|$ & + \zeroone{\texttt{Mutual}} {\tt CoInductive} \nelist{\inductivebody}{with} + \verb:.: \\ + & & \\ +{\inductivebody} & ::= & +{\ident} \zeroone{{\tt [} {\params} {\tt ]}} \verb.:. {\term} + \verb.:=. + \sequence{\constructor}{|} \\ + & & \\ +{\constructor} & ::= & {\ident} \verb.:. {\term} \\ + & &\\ + +{\fixpoint} & ::= & {\tt Fixpoint} \nelist{\fixpointbody}{with} + \verb:.: \\ +& $|$ & {\tt CoFixpoint} \nelist{\cofixpointbody}{with} + \verb:.: \\ + & &\\ + +{\statement} & ::= & {\tt Theorem} {\ident} {\tt :} {\term} \verb:.: \\ + & $|$ & {\tt Lemma} {\ident} {\tt :} {\term} \verb:.: \\ + & $|$ & {\tt Definition} {\ident} {\tt :} {\term} \verb:.: \\ + & & \\ + +{\proof} & ::= & {\tt Proof} {\tt .} {\dots} {\tt Qed} {\tt .}\\ + & $|$ & {\tt Proof} {\tt .} {\dots} {\tt Defined} {\tt .}\\ +\hline +\end{tabular} +\caption{Syntax of sentences} +\end{figure} +The different kinds of command are described hereafter. They all suppose +that the terms occurring in the sentences are well-typed. + +\subsection{Declarations}\index{Declarations}\label{Declarations} +The declaration mechanism allows the user to specify his own basic +objects. Declared objects play the role of axioms or parameters in +mathematics. A declared object is an {\ident} associated to a \term. A +declaration is accepted by {\Coq} iff this {\term} is a correct type +in the current context of the declaration and \ident\ was +not previously defined in the same module. This {\term} +is considered to be the type, or specification, of the \ident. + +\subsubsection{{\tt Axiom {\ident} : {\term}}.} +\comindex{Axiom} +\label{Axiom} +This command links {\term} to the name {\ident} as its specification in the +global context. The fact asserted by {\term} is thus assumed +as a postulate. + +\begin{ErrMsgs} +\item \errindex{Clash with previous constant {\ident}} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Parameter {\ident} : {\term}.} + \comindex{Parameter}\\ + Is equivalent to {\tt Axiom {\ident} : {\term}} +\item {\tt Parameter \nelist{\nelist{\ident}{,} : {\term}}{;} {\tt .}} \\ +% Is equivalent to {\tt Axiom {\lident} : {\term}} + Links the {\term}'s to the names comprising the lists \nelist{\nelist{\ident}{,} : {\term}}{;}. +\end{Variants} + +\noindent {\bf Remark: } It is possible to replace {\tt Parameter} by +{\tt Parameters} when more than one parameter are given. + +\subsubsection{{\tt Variable {\ident} : {\term}}.}\comindex{Variable} +\comindex{Variables} +This command links {\term} to the name {\ident} in the context of the +current section (see \ref{Section} for a description of the section +mechanism). The name {\ident} will be unknown when the current +section will be closed. One says that the variable is {\em + discharged}. Using the {\tt Variable} command out of any section is +equivalent to {\tt Axiom}. + +\begin{ErrMsgs} +\item \errindex{Clash with previous constant {\ident}} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Variable \nelist{\nelist{\ident}{,}:{\term}}{;} {\tt .}}\\ + Links {\term} to the + names comprising the list \nelist{\nelist{\ident}{,}:{\term}}{;} +\item {\tt Hypothesis \nelist{\nelist{\ident}{,} $\;$:$\;$ {\term}}{;} {\tt + .}} \comindex{Hypothesis}\\ % Ligne trop longue + \texttt{Hypothsis} is a synonymous of \texttt{Variable} +\end{Variants} + +\noindent {\bf Remark: } It is possible to replace {\tt Variable} by +{\tt Variables} and \ml{Hypothesis} by {\tt Hypotheses} + when more than one variable or one hypothesis are given. + +It is advised to use the keywords \verb:Axiom: and \verb:Hypothesis: +for logical postulates (i.e. when the assertion {\term} is of sort +\verb:Prop:), and to use the keywords \verb:Parameter: and +\verb:Variable: in other cases (corresponding to the declaration of an +abstract mathematical entity). + +\subsection{Definitions}\index{Definitions}\label{Simpl-definitions} +Definitions differ from declarations since they allow to give a name +to a term whereas declarations were just giving a type to a name. That +is to say that the name of a defined object can be replaced at any +time by its definition. This replacement is called +$\delta$-conversion\index{delta-reduction@$\delta$-reduction} (see section +\ref{delta}). A defined object is accepted by the system iff the +defining term is well-typed in the current context of the definition. +Then the type of the name is the type of term. The defined name is +called a {\em constant}\index{Constant} and one says that {\it the + constant is added to the environment}\index{Environment}. + +A formal presentation of constants and environments is given in +section \ref{Cic-definitions}. + + +\subsubsection{\tt Definition {\ident} := {\term}.} +\comindex{Definition} +This command binds the value {\term} to the name {\ident} in the +environment, provided that {\term} is well-typed. + +\begin{ErrMsgs} +\item \errindex{Clash with previous constant {\ident}} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Definition {\ident} : {\term$_1$} := {\term$_2$}.} It + checks that the type of {\term$_2$} is definitionally equal to + {\term$_1$}, and registers {\ident} as being of type {\term$_1$}, + and bound to value {\term$_2$}. +\end{Variants} + +\begin{ErrMsgs} +\item \errindex{In environment \dots the term: {\term$_2$} does not have type + {\term$_1$}}.\\ + \texttt{Actually, it has type {\term$_3$}}. +\end{ErrMsgs} + +\SeeAlso sections \ref{Opaque}, \ref{Transparent}, \ref{Unfold} + +\subsubsection{\tt Local {\ident} := {\term}.}\comindex{Local} +This command binds the value {\term} to the name {\ident} in the +environment of the current section. The name {\ident} will be unknown +when the current section will be closed and all occurrences of +{\ident} in persistent objects (such as theorems) defined within the +section will be replaced by \term. One can say that the {\tt Local} +definition is a kind of {\em macro}. + +\begin{ErrMsgs} +\item \errindex{Clash with previous constant {\ident}} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Local {\ident} : {\term$_1$} := {\term$_2$}.} +\end{Variants} + +\SeeAlso \ref{Section} (section mechanism), \ref{Opaque}, +\ref{Transparent} (opaque/transparent constants), \ref{Unfold} + +% Let comme forme de Definition n'existe plus +% +%\subsubsection{\tt Let {\ident} := {\term}.} +%\comindex{Let} + +%This command makes definition that are stronger than \texttt{Local}, +%and weaker than \texttt{Definition}. The name {\ident} will be kown in the +%current section and after having closed the current section, but will +%be unknown after closing the section above the current section. + +%\begin{Variants} +%\item {\tt Local {\ident} : {\term$_1$} := {\term$_2$}.} +%\end{Variants} + +%\SeeAlso \ref{Section} + +\subsection{Inductive definitions} +\index{Inductive definitions} \label{gal_Inductive_Definitions} +\comindex{Inductive}\label{Inductive} + +We gradually explain simple inductive types, simple +annotated inductive types, simple parametric inductive types, +mutually inductive types. We explain also co-inductive types. + +\subsubsection{Simple inductive types} + +The definition of a simple inductive type has the following form: + +\medskip +{\tt +\begin{tabular}{l} +Inductive {\ident} : {\sort} := \\ +\begin{tabular}{clcl} + & {\ident$_1$} &:& {\type$_1$} \\ + | & {\ldots} && \\ + | & {\ident$_n$} &:& {\type$_n$} +\end{tabular} +\end{tabular} +} +\medskip + +The name {\ident} is the name of the inductively defined type and +{\sort} is the universes where it lives. +The names {\ident$_1$}, {\ldots}, {\ident$_n$} +are the names of its constructors and {\type$_1$}, {\ldots}, +{\type$_n$} their respective types. The types of the constructors have +to satisfy a {\em positivity condition} (see section \ref{Positivity}) +for {\ident}. This condition ensures the soundness of the inductive +definition. If this is the case, the constants {\ident}, +{\ident$_1$}, {\ldots}, {\ident$_n$} are added to the environment with +their respective types. Accordingly to the universe where +the inductive type lives({\it e.g.} its type {\sort}), {\Coq} provides a +number of destructors for {\ident}. Destructors are named +{\ident}{\tt\_ind}, {\ident}{\tt \_rec} or {\ident}{\tt \_rect} which +respectively correspond to elimination principles on {\tt Prop}, {\tt +Set} and {\tt Type}. The type of the destructors expresses structural +induction/recursion principles over objects of {\ident}. We give below +two examples of the use of the {\tt Inductive} definitions. + +The set of natural numbers is defined as: +\begin{coq_example} +Inductive nat : Set := O : nat | S : nat -> nat. +\end{coq_example} + +The type {\tt nat} is defined as the least \verb:Set: containing {\tt + O} and closed by the {\tt S} constructor. The constants {\tt nat}, +{\tt O} and {\tt S} are added to the environment. + +Now let us have a look at the elimination principles. They are three : +{\tt nat\_ind}, {\tt nat\_rec} and {\tt nat\_rect}. The type of {\tt + nat\_ind} is: +\begin{coq_example} +Check nat_ind. +\end{coq_example} + +This is the well known structural induction principle over natural +numbers, i.e. the second-order form of Peano's induction principle. +It allows to prove some universal property of natural numbers ({\tt +(n:nat)(P n)}) by induction on {\tt n}. Recall that {\tt (n:nat)(P n)} +is \gallina's syntax for the universal quantification $\forall +n:nat\cdot P(n).$\\ The types of {\tt nat\_rec} and {\tt nat\_rect} +are similar, except that they pertain to {\tt (P:nat->Set)} and {\tt +(P:nat->Type)} respectively . They correspond to primitive induction +principles (allowing dependent types) respectively over sorts +\verb:Set: and \verb:Type:. The constant {\ident}{\tt \_ind} is always +provided, whereas {\ident}{\tt \_rec} and {\ident}{\tt \_rect} can be +impossible to derive (for example, when {\ident} is a proposition). + +\subsubsection{Simple annotated inductive types} + +In an annotated inductive types, the universe where the inductive +type is defined is no longer a simple sort, but what is called an +arity, which is a type whose conclusion is a sort. + +As an example of annotated inductive types, let us define the +$even$ predicate: + +\begin{coq_example} +Inductive even : nat->Prop := + | even_0 : (even O) + | even_SS : (n:nat)(even n)->(even (S (S n))). +\end{coq_example} + +The type {\tt nat->Prop} means that {\tt even} is a unary predicate +(inductively defined) over natural numbers. The type of its two +constructors are the defining clauses of the predicate {\tt even}. The +type of {\tt even\_ind} is: + +\begin{coq_example} +Check even_ind. +\end{coq_example} + +From a mathematical point of view it asserts that the natural numbers +satisfying the predicate {\tt even} are exactly the naturals satisfying +the clauses {\tt even\_0} or {\tt even\_SS}. This is why, when we want +to prove any predicate {\tt P} over elements of {\tt even}, it is +enough to prove it for {\tt O} and to prove that if any natural number +{\tt n} satisfies {\tt P} its double successor {\tt (S (S n))} +satisfies also {\tt P}. This is indeed analogous to the structural +induction principle we got for {\tt nat}. + +\begin{ErrMsgs} +\item \errindex{Non strictly positive occurrence of {\ident} in {\type}} +\item \errindex{Type of Constructor not well-formed} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Inductive {\ident} [ {\params} ] : {\term} := + {\ident$_1$}:{\term$_1$} | {\ldots} | {\ident$_n$}:\term$_n$.}\\ Allows + to define parameterized inductive types.\\ + For instance, one can define + parameterized lists as: +\begin{coq_example*} +Inductive list [X:Set] : Set := + Nil : (list X) | Cons : X->(list X)->(list X). +\end{coq_example*} +Notice that, in the type of {\tt Nil} and {\tt Cons}, we write {\tt + (list X)} and not just {\tt list}.\\ The constants {\tt Nil} and +{\tt Cons} will have respectively types: + +\begin{coq_example} +Check Nil. +\end{coq_example} +and + +\begin{coq_example} +Check Cons. +\end{coq_example} + +Types of destructors will be also quantified with {\tt (X:Set)}. +\item {\tt Inductive {\sort} {\ident} := +{\ident$_1$}:{\term$_1$} | {\ldots} | {\ident$_n$}:\term$_n$.}\\ +with {\sort} being one of {\tt Prop, Type, Set} is +equivalent to \\ {\tt Inductive {\ident} : {\sort} := + {\ident$_1$}:{\term$_1$} | {\ldots} | {\ident$_n$}:\term$_n$.} +\item {\tt Inductive {\sort} {\ident} [ {\params} ]:= +{\ident$_1$}:{\term$_1$} | {\ldots} | {\ident$_n$}:\term$_n$.}\\ + Same as before but with parameters. +\end{Variants} + +\SeeAlso sections \ref{Cic-inductive-definitions}, \ref{Elim} + +\subsubsection{Mutually inductive types} +\comindex{Mutual Inductive}\label{Mutual-Inductive} + +The definition of a block of mutually inductive types has the form: + +\medskip +{\tt +\begin{tabular}{l} +Inductive {\ident$_1$} : {\type$_1$} := \\ +\begin{tabular}{clcl} + & {\ident$_1^1$} &:& {\type$_1^1$} \\ + | & {\ldots} && \\ + | & {\ident$_{n_1}^1$} &:& {\type$_{n_1}^1$} +\end{tabular} \\ +with\\ +~{\ldots} \\ +with {\ident$_m$} : {\type$_m$} := \\ +\begin{tabular}{clcl} + & {\ident$_1^m$} &:& {\type$_1^m$} \\ + | & {\ldots} \\ + | & {\ident$_{n_m}^m$} &:& {\type$_{n_m}^m$}. +\end{tabular} +\end{tabular} +} +\medskip + +\noindent {\bf Remark: } The word {\tt Mutual} can be optionally +inserted in front of {\tt Inductive}. + +It has the same semantics as the above {\tt Inductive} definition for +each \ident$_1$, {\ldots}, \ident$_m$. All names \ident$_1$, {\ldots}, +\ident$_m$ and \ident$_1^1$, \dots, \ident$_{n_m}^m$ are +simultaneously added to the environment. Then +well-typing of constructors can be checked. Each one of the +\ident$_1$, {\ldots}, \ident$_m$ can be used on its own. + +It is also possible to parameterize these inductive definitions. +However, parameters correspond to a local +context in which the whole set of inductive declarations is done. For +this reason, the parameters must be strictly the same for each +inductive types The extented syntax is: + +\medskip +{\tt +Inductive {{\ident$_1$} [{\rm\sl params} ] : {\type$_1$} := \\ +\mbox{}\hspace{0.4cm} {\ident$_1^1$} : {\type$_1^1$} \\ +\mbox{}\hspace{0.1cm}| .. \\ +\mbox{}\hspace{0.1cm}| {\ident$_{n_1}^1$} : {\type$_{n_1}^1$} \\ +with\\ +\mbox{}\hspace{0.1cm} .. \\ +with {\ident$_m$} [{\rm\sl params} ] : {\type$_m$} := \\ +\mbox{}\hspace{0.4cm}{\ident$_1^m$} : {\type$_1^m$} \\ +\mbox{}\hspace{0.1cm}| .. \\ +\mbox{}\hspace{0.1cm}| {\ident$_{n_m}^m$} : {\type$_{n_m}^m$}. +}} +\medskip + +\Example +The typical example of a mutual inductive data type is the one for +trees and forests. We assume given two types $A$ and $B$ as variables. +It can be declared the following way. + +\begin{coq_example*} +Variables A,B:Set. +Inductive tree : Set := node : A -> forest -> tree +with forest : Set := + | leaf : B -> forest + | cons : tree -> forest -> forest. +\end{coq_example*} + +This declaration generates automatically six induction +principles. They are respectively +called {\tt tree\_rec}, {\tt tree\_ind}, {\tt + tree\_rect}, {\tt forest\_rec}, {\tt forest\_ind}, {\tt + forest\_rect}. These ones are not the most general ones but are +just the induction principles corresponding to each inductive part +seen as a single inductive definition. + +To illustrate this point on our example, we give the types of {\tt + tree\_rec} and {\tt forest\_rec}. + +\begin{coq_example} +Check tree_rec. +Check forest_rec. +\end{coq_example} + +Assume we want to parameterize our mutual inductive definitions with +the two type variables $A$ and $B$, the declaration should be done the +following way: + +\begin{coq_eval} +Reset tree. +\end{coq_eval} +\begin{coq_example*} +Inductive + tree [A,B:Set] : Set := node : A -> (forest A B) -> (tree A B) +with forest [A,B:Set] : Set := leaf : B -> (forest A B) + | cons : (tree A B) -> (forest A B) -> (forest A B). +\end{coq_example*} +\begin{coq_eval} +Save State toto. +\end{coq_eval} + +Assume we define an inductive definition inside a section. When the +section is closed, the variables declared in the section and occurring +free in the declaration are added as parameters to the inductive +definition. + +\SeeAlso \ref{Section} + +\subsubsection{Co-inductive types} +\comindex{CoInductive} + +The objects of an inductive type are well-founded with respect to the +constructors of the type. In other words, such objects contain only a +{\it finite} number constructors. Co-inductive types arise from +relaxing this condition, and admitting types whose objects contain an +infinity of constructors. Infinite objects are introduced by a +non-ending (but effective) process of construction, defined in terms +of the constructors of the type. + +An example of a co-inductive type is the type of infinite sequences of +natural numbers, usually called streams. It can be introduced in \Coq\ +using the \texttt{CoInductive} command: +\begin{coq_example} +CoInductive Set Stream := Seq : nat->Stream->Stream. +\end{coq_example} + +The syntax of this command is the same as the command \texttt{Inductive} +(cf. section \ref{gal_Inductive_Definitions}). Notice that no +principle of induction is derived from the definition of a +co-inductive type, since such principles only make sense for inductive +ones. For co-inductive ones, the only elimination principle is case +analysis. For example, the usual destructors on streams +\texttt{hd:Stream->nat} and \texttt{tl:Str->Str} can be defined as +follows: +\begin{coq_example} +Definition hd := [x:Stream]Cases x of (Seq a s) => a end. +Definition tl := [x:Stream]Cases x of (Seq a s) => s end. +\end{coq_example} + +Definition of co-inductive predicates and blocks of mutually +co-inductive definitions are also allowed. An example of a +co-inductive predicate is the extensional equality on streams: + +\begin{coq_example} +CoInductive EqSt : Stream->Stream->Prop := + eqst : (s1,s2:Stream) + (hd s1)=(hd s2)-> + (EqSt (tl s1) (tl s2))->(EqSt s1 s2). +\end{coq_example} + +In order to prove the extensionally equality of two streams $s_1$ and +$s_2$ we have to construct and infinite proof of equality, that is, +an infinite object of type $(\texttt{EqSt}\;s_1\;s_2)$. We will see +how to introduce infinite objects in section \ref{CoFixpoint}. + +\subsection{Definition of recursive functions} + +\subsubsection{\tt Fixpoint {\ident} [ \ident$_1$ : \type$_1$ ] : +\type$_0$ := \term$_0$} +\comindex{Fixpoint}\label{Fixpoint} + +This command allows to define inductive objects using a fixed point +construction. The meaning of this declaration is to define {\it +ident} a recursive function with one argument \ident$_1$ of type +\term$_1$ such that ({\it ident}~\ident$_1$) has type \type$_0$ and is +equivalent to the expression \term$_0$. The type of the {\ident} is +consequently {(\ident$_1$ : \type$_1$)\type$_0$} and the value is +equivalent to [\ident$_1$ : \type$_1$]\term$_0$. The argument +{\ident$_1$} (of type {\type$_1$}) is called the {\em recursive +variable} of {\ident}. Its type should be an inductive definition. + +To be accepted, a {\tt Fixpoint} definition has to satisfy some +syntactical constraints on this recursive variable. They are needed to +ensure that the {\tt Fixpoint} definition always terminates. For +instance, one can define the addition function as : + +\begin{coq_example} +Fixpoint add [n:nat] : nat->nat + := [m:nat]Cases n of O => m | (S p) => (S (add p m)) end. +\end{coq_example} + +The {\tt Cases} operator matches a value (here \verb: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 \verb:n: +equals \verb:O: we return \verb:m:, and when \verb:n: equals +\verb:(S p): we return \verb:(S (add p m)):. + +The {\tt Cases} operator is formally described +in detail in section \ref{Caseexpr}. The system recognizes that in +the inductive call {\tt (add p m)} the first argument actually +decreases because it is a {\em pattern variable} coming from {\tt Cases + n of}. + +\begin{Variants} +\item {\tt Fixpoint {\ident} [ {\params} ] : \type$_0$ := +\term$_0$.}\\ + It declares a list of identifiers with their type + usable in the type \type$_0$ and the definition body \term$_0$ + and the last identifier in {\params} is the recursion variable. +\item {\tt Fixpoint {\ident$_1$} [ {\params$_1$} ] : + {\type$_1$} := {\term$_1$}\\ + with {\ldots} \\ + with {\ident$_m$} [ {\params$_m$} ] : {\type$_m$} := + {\type$_m$}}\\ + Allows to define simultaneously {\ident$_1$}, {\ldots}, + {\ident$_m$}. +\end{Variants} + +\Example The following definition is not correct and generates an +error message: + +\begin{coq_example} +Fixpoint wrongplus [n:nat] : nat->nat + := [m:nat]Cases m of O => n | (S p) => (S (wrongplus n p)) end. +\end{coq_example} + +because the declared decreasing argument {\tt n} actually does not +decrease in the recursive call. The function computing the addition +over the second argument should rather be written: + +\begin{coq_example*} +Fixpoint plus [n,m:nat] : nat + := Cases m of O => n | (S p) => (S (plus n p)) end. +\end{coq_example*} + +The ordinary match operation on natural numbers can be mimicked in the +following way. +\begin{coq_example*} +Fixpoint nat_match [C:Set;f0:C;fS:nat->C->C;n:nat] : C + := Cases n of O => f0 | (S p) => (fS p (nat_match C f0 fS p)) end. +\end{coq_example*} +The recursive call may not only be on direct subterms of the recursive +variable {\tt n} but also on a deeper subterm and we can directly +write the function {\tt mod2} which gives the remainder modulo 2 of a +natural number. +\begin{coq_example*} +Fixpoint mod2 [n:nat] : nat + := Cases n of + O => O + | (S p) => Cases p of O => (S O) | (S q) => (mod2 q) end + end. +\end{coq_example*} +In order to keep the strong normalisation property, the fixed point +reduction will only be performed when the argument in position of the +recursive variable (whose type should be in an inductive definition) +starts with a constructor. + +The {\tt Fixpoint} construction enjoys also the {\tt with} extension +to define functions over mutually defined inductive types or more +generally any mutually recursive definitions. + +\Example +The size of trees and forests can be defined the following way: +\begin{coq_eval} +Restore State Initial. +Variables A,B:Set. +Inductive tree : Set := node : A -> forest -> tree +with forest : Set := leaf : B -> forest + | cons : tree -> forest -> forest. +\end{coq_eval} +\begin{coq_example*} +Fixpoint tree_size [t:tree] : nat := + Cases t of (node a f) => (S (forest_size f)) end +with forest_size [f:forest] : nat := + Cases f of (leaf b) => (S O) + | (cons t f') => (plus (tree_size t) (forest_size f')) + end. +\end{coq_example*} +A generic command {\tt Scheme} is useful to build automatically various +mutual induction principles. It is described in section \ref{Scheme}. + +\subsubsection{{\tt CoFixpoint} {\ident} : +\type$_0$ := \term$_0$.}\comindex{CoFixpoint}\label{CoFixpoint} + +The {\tt CoFixpoint} command introduces a method for constructing an +infinite object of a coinduc\-tive type. For example, the stream +containing all natural numbers can be introduced applying the +following method to the number \texttt{O}: + +\begin{coq_example*} +CoInductive Set Stream := Seq : nat->Stream->Stream. +Definition hd := [x:Stream]Cases x of (Seq a s) => a end. +Definition tl := [x:Stream]Cases x of (Seq a s) => s end. +\end{coq_example*} +\begin{coq_example} +CoFixpoint from : nat->Stream := [n:nat](Seq n (from (S n))). +\end{coq_example} + +Oppositely to recursive ones, there is no decreasing argument in a +co-recursive definition. To be admissible, a method of construction +must provide at least one extra constructor of the infinite object for +each iteration. A syntactical guard condition is imposed on +co-recursive definitions in order to ensure this: each recursive call +in the definition must be protected by at least one constructor, and +only by constructors. That is the case in the former definition, where +the single recursive call of \texttt{from} is guarded by an +application of \texttt{Seq}. On the contrary, the following recursive +function does not satisfy the guard condition: + +\begin{coq_example*} +CoFixpoint filter : (nat->bool)->Stream->Stream := + [p:nat->bool] + [s:Stream] + if (p (hd s)) then (Seq (hd s) (filter p (tl s))) + else (filter p (tl s)). +\end{coq_example*} + +\noindent Notice that the definition contains an unguarded recursive +call of \texttt{filter} on the \texttt{else} branch of the test. + +The elimination of co-recursive definition is done lazily, i.e. the +definition is expanded only when it occurs at the head of an +application which is the argument of a case expression. Isolate, it +is considered as a canonical expression which is completely +evaluated. We can test this using the command \texttt{Eval}, +which computes the normal forms of a term: + +\begin{coq_example} +Eval Compute in (from O). +Eval Compute in (hd (from O)). +Eval Compute in (tl (from O)). +\end{coq_example} + +As in the \texttt{Fixpoint} command (cf. section~\ref{Fixpoint}), it +is possible to introduce a block of mutually dependent methods. The +general syntax for this case is: + +{\tt CoFixpoint {\ident$_1$} :{\type$_1$} := {\term$_1$}\\ + with\\ + \mbox{}\hspace{0.1cm} $\ldots$ \\ + with {\ident$_m$} : {\type$_m$} := {\term$_m$}} + +\subsection{Statement and proofs} + +A statement claims a goal of which the proof is then interactively done +using tactics. More on the proof editing mode, statements and proofs can be +found in chapter \ref{Proof-handling}. + +\subsubsection{\tt Theorem {\ident} : {\type}.} +\comindex{Theorem} +This command binds {\type} to the name {\ident} in the +environment, provided that a proof of {\type} is next given. + +After a statement, Coq needs a proof. + +\begin{Variants} + +\item {\tt Lemma {\ident} : {\type}.}\comindex{Lemma}\\ +It is a synonymous of \texttt{Theorem} +\item {\tt Remark {\ident} : {\type}.}\comindex{Remark}\\ +Same as {\tt Theorem} except +that if this statement is in a section then the name {\ident} will be unknown +when the current section (see \ref{Section}) will be closed. All +proofs of persistent objects (such as theorems) referring to {\ident} +within the section will be replaced by the proof of {\ident}. +\item {\tt Definition {\ident} : {\type}.} \\ +Allow to define a term of type {\type} using the proof editing mode. It +behaves as {\tt Theorem} except the defined term will be transparent (see +\ref{Transparent}, \ref{Unfold}). +\end{Variants} + +\subsubsection{{\tt Proof} {\tt .} \dots {\tt Qed} {\tt .}} + +A proof starts by the keyword {\tt Proof}. Then {\Coq} enters the +proof editing mode until the proof is completed. The proof editing +mode essentially contains tactics that are described in chapter +\ref{Tactics}. Besides tactics, there are commands to manage the proof +editing mode. They are described in chapter \ref{Proof-handling}. When +the proof is completed it should be validated and put in the +environment using the keyword {\tt Qed}. +\medskip + +\ErrMsg +\begin{enumerate} +\item \errindex{Clash with previous constant {\ident}} +\end{enumerate} + +\begin{Remarks} +\item Several statements can be simultaneously opened. +\item Not only other statements but any vernacular command can be given +within the proof editing mode. In this case, the command is +understood as if it would have been given before the statements still to be +proved. +\item {\tt Proof} is recommended but can currently be omitted. On the +opposite, {\tt Qed} is mandatory to validate a proof. +\end{Remarks} + +\begin{Variants} +\item {\tt Proof} {\tt .} \dots {\tt Defined} {\tt .}\\ + \comindex{Proof} + Same as {\tt Proof} {\tt .} \dots {\tt Qed} {\tt .} but it is + intended to surround a definition built using the proof-editing mode. +\item {\tt Proof} {\tt .} \dots {\tt Save.}\\ + Same as {\tt Proof} {\tt .} \dots {\tt Qed} {\tt .} +\item {\tt Goal} \type \dots {\tt Save} \ident \\ + Same as {\tt Lemma} \ident {\tt :} \type \dots {\tt Save.} + This is intended to be used in the interactive mode. Conversely to named + lemmas, anonymous goals cannot be nested. +\end{Variants} +\comindex{Proof} +\comindex{Qed} +\comindex{Save} +\comindex{Goal} + +% Local Variables: +% mode: LaTeX +% TeX-master: "Reference-Manual" +% End: + +% $Id$ diff --git a/doc/RefMan-ind.tex b/doc/RefMan-ind.tex new file mode 100755 index 000000000..6ac276d85 --- /dev/null +++ b/doc/RefMan-ind.tex @@ -0,0 +1,493 @@ + +%\documentstyle[11pt]{article} +%\input{title} + +%\include{macros} +%\makeindex + +%\begin{document} +%\coverpage{The module {\tt Equality}}{Cristina CORNES} + +%\tableofcontents + +\chapter{Tactics for inductive types and families} +\label{Addoc-equality} + +This chapter details a few special tactics useful for inferring facts +from inductive hypotheses. They can be considered as tools that +macro-generate complicated uses of the basic elimination tactics for +inductive types. + +Sections \ref{inversion_introduction} to \ref{inversion_using} present +inversion tactics and section \ref{scheme} describes +a command {\tt Scheme} for automatic generation of induction schemes +for mutual inductive types. + +%\end{document} +%\documentstyle[11pt]{article} +%\input{title} + +%\begin{document} +%\coverpage{Module Inv: Inversion Tactics}{Cristina CORNES} + +\section{Generalities about inversion} +\label{inversion_introduction} +When working with (co)inductive predicates, we are very often faced to +some of these situations: +\begin{itemize} +\item we have an inconsistent instance of an inductive predicate in the + local context of hypotheses. Thus, the current goal can be trivially + proved by absurdity. + +\item we have a hypothesis that is an instance of an inductive + predicate, and the instance has some variables whose constraints we + would like to derive. +\end{itemize} + +The inversion tactics are very useful to simplify the work in these +cases. Inversion tools can be classified in three groups: +\begin{enumerate} +\item tactics for inverting an instance without stocking the inversion + lemma in the context: + (\texttt{Dependent}) \texttt{Inversion} and + (\texttt{Dependent}) \texttt{Inversion\_clear}. +\item commands for generating and stocking in the context the inversion + lemma corresponding to an instance: \texttt{Derive} + (\texttt{Dependent}) \texttt{Inversion}, \texttt{Derive} + (\texttt{Dependent}) \texttt{Inversion\_clear}. +\item tactics for inverting an instance using an already defined + inversion lemma: \texttt{Inversion \ldots using}. +\end{enumerate} + +These tactics work for inductive types of arity $(\vec{x}:\vec{T})s$ +where $s \in \{Prop,Set,Type\}$. Sections \ref{inversion_primitive}, +\ref{inversion_derivation} and \ref{inversion_using} +describe respectively each group of tools. + +As 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.\\ + +Let's consider the relation \texttt{Le} over natural numbers and the +following variables: + +\begin{coq_eval} +Restore State Initial. +\end{coq_eval} + +\begin{coq_example*} +Inductive Le : nat->nat->Set := + LeO : (n:nat)(Le O n) | LeS : (n,m:nat) (Le n m)-> (Le (S n) (S m)). +Variable P:nat->nat->Prop. +Variable Q:(n,m:nat)(Le n m)->Prop. +\end{coq_example*} + +For example purposes we defined \verb+Le: nat->nat->Set+ + but we may have defined +it \texttt{Le} of type \verb+nat->nat->Prop+ or \verb+nat->nat->Type+. + + +\section{Inverting an instance} +\label{inversion_primitive} +\subsection{The non dependent case} +\begin{itemize} + +\item \texttt{Inversion\_clear} \ident~\\ +\index{Inversion-clear@{\tt Inversion\_clear}} + Let the type of \ident~ in the local context be $(I~\vec{t})$, + where $I$ is a (co)inductive predicate. Then, + \texttt{Inversion} applied to \ident~ derives for each possible + constructor $c_i$ of $(I~\vec{t})$, {\bf all} the necessary + conditions that should hold for the instance $(I~\vec{t})$ to be + proved by $c_i$. Finally it erases \ident~ from the context. + + + +For example, consider the goal: +\begin{coq_eval} +Lemma ex : (n,m:nat)(Le (S n) m)->(P n m). +Intros. +\end{coq_eval} + +\begin{coq_example} +Show. +\end{coq_example} + +To prove the goal we may need to reason by cases on \texttt{H} and to + derive that \texttt{m} is necessarily of +the form $(S~m_0)$ for certain $m_0$ and that $(Le~n~m_0)$. +Deriving these conditions corresponds to prove that the +only possible constructor of \texttt{(Le (S n) m)} is +\texttt{LeS} and that we can invert the +\texttt{->} in the type of \texttt{LeS}. +This inversion is possible because \texttt{Le} is the smallest set closed by +the constructors \texttt{LeO} and \texttt{LeS}. + + +\begin{coq_example} +Inversion_clear H. +\end{coq_example} + +Note that \texttt{m} has been substituted in the goal for \texttt{(S m0)} +and that the hypothesis \texttt{(Le n m0)} has been added to the +context. + +\item \texttt{Inversion} \ident~\\ +\index{Inversion@{\tt Inversion}} + This tactic differs from {\tt Inversion\_clear} in the fact that + it adds the equality constraints in the context and + it does not erase the hypothesis \ident. + + +In the previous example, {\tt Inversion\_clear} +has substituted \texttt{m} by \texttt{(S m0)}. Sometimes it is +interesting to have the equality \texttt{m=(S m0)} in the +context to use it after. In that case we can use \texttt{Inversion} that +does not clear the equalities: + +\begin{coq_example*} +Undo. +\end{coq_example*} +\begin{coq_example} +Inversion H. +\end{coq_example} + +\begin{coq_eval} +Undo. +\end{coq_eval} + +Note that the hypothesis \texttt{(S m0)=m} has been deduced and +\texttt{H} has not been cleared from the context. + +\end{itemize} + +\begin{Variants} + +\item \texttt{Inversion\_clear } \ident~ \texttt{in} \ident$_1$ \ldots + \ident$_n$\\ +\index{Inversion_clear...in@{\tt Inversion\_clear...in}} + Let \ident$_1$ \ldots \ident$_n$, be identifiers in the local context. This + tactic behaves as generalizing \ident$_1$ \ldots \ident$_n$, and then performing + {\tt Inversion\_clear}. + +\item \texttt{Inversion } \ident~ \texttt{in} \ident$_1$ \ldots \ident$_n$\\ +\index{Inversion ... in@{\tt Inversion ... in}} + Let \ident$_1$ \ldots \ident$_n$, be identifiers in the local context. This + tactic behaves as generalizing \ident$_1$ \ldots \ident$_n$, and then performing + \texttt{Inversion}. + + +\item \texttt{Simple Inversion} \ident~ \\ +\index{Simple Inversion@{\tt Simple Inversion}} + It is a very primitive inversion tactic that derives all the necessary + equalities but it does not simplify + the constraints as \texttt{Inversion} and + {\tt Inversion\_clear} do. + +\end{Variants} + + +\subsection{The dependent case} +\begin{itemize} +\item \texttt{Dependent Inversion\_clear} \ident~\\ +\index{Dependent Inversion-clear@{\tt Dependent Inversion\_clear}} + Let the type of \ident~ in the local context be $(I~\vec{t})$, + where $I$ is a (co)inductive predicate, and let the goal depend both on + $\vec{t}$ and \ident. Then, + \texttt{Dependent Inversion\_clear} applied to \ident~ derives + for each possible constructor $c_i$ of $(I~\vec{t})$, {\bf all} the + necessary conditions that should hold for the instance $(I~\vec{t})$ to be + proved by $c_i$. It also substitutes \ident~ for the corresponding + term in the goal and it erases \ident~ from the context. + + +For example, consider the goal: +\begin{coq_eval} +Lemma ex_dep : (n,m:nat)(H:(Le (S n) m))(Q (S n) m H). +Intros. +\end{coq_eval} + +\begin{coq_example} +Show. +\end{coq_example} + +As \texttt{H} occurs in the goal, we may want to reason by cases on its +structure and so, we would like inversion tactics to +substitute \texttt{H} by the corresponding term in constructor form. +Neither \texttt{Inversion} nor {\tt Inversion\_clear} make such a +substitution. To have such a behavior we use the dependent inversion tactics: + +\begin{coq_example} +Dependent Inversion_clear H. +\end{coq_example} + +Note that \texttt{H} has been substituted by \texttt{(LeS n m0 l)} and +\texttt{m} by \texttt{(S m0)}. + + +\end{itemize} + +\begin{Variants} + +\item \texttt{Dependent Inversion\_clear } \ident~ \texttt{ with } \term\\ +\index{Dependent Inversion_clear...with@{\tt Dependent Inversion\_clear...with}} + \noindent Behaves as \texttt{Dependent Inversion\_clear} but allows to give + explicitly the good generalization of the goal. It is useful when + the system fails to generalize the goal automatically. If + \ident~ has type $(I~\vec{t})$ and $I$ has type + $(\vec{x}:\vec{T})s$, then \term~ must be of type + $I:(\vec{x}:\vec{T})(I~\vec{x})\rightarrow s'$ where $s'$ is the + type of the goal. + + + +\item \texttt{Dependent Inversion} \ident~\\ +\index{Dependent Inversion@{\tt Dependent Inversion}} + This tactic differs from \texttt{Dependent Inversion\_clear} in the fact that + it also adds the equality constraints in the context and + it does not erase the hypothesis \ident~. + +\item \texttt{Dependent Inversion } \ident~ \texttt{ with } \term \\ +\index{Dependent Inversion...with@{\tt Dependent Inversion...with}} + Analogous to \texttt{Dependent Inversion\_clear .. with..} above. +\end{Variants} + + + +\section{Deriving the inversion lemmas} +\label{inversion_derivation} +\subsection{The non dependent case} + +The tactics (\texttt{Dependent}) \texttt{Inversion} and (\texttt{Dependent}) +{\tt Inversion\_clear} work on a +certain instance $(I~\vec{t})$ of an inductive predicate. At each +application, they inspect the given instance and derive the +corresponding inversion lemma. If we have to invert the same +instance several times it is recommended to stock the lemma in the +context and to reuse it whenever we need it. + +The families of commands \texttt{Derive Inversion}, \texttt{Derive +Dependent Inversion}, \texttt{Derive} \\ {\tt Inversion\_clear} and \texttt{Derive Dependent Inversion\_clear} +allow to generate inversion lemmas for given instances and sorts. Next +section describes the tactic \texttt{Inversion}$\ldots$\texttt{using} that refines the +goal with a specified inversion lemma. + +\begin{itemize} + +\item \texttt{Derive Inversion\_clear} \ident~ \texttt{with} + $(\vec{x}:\vec{T})(I~\vec{t})$ \texttt{Sort} \sort~ \\ +\index{Derive Inversion_clear...with@{\tt Derive Inversion\_clear...with}} + Let $I$ be an inductive predicate and $\vec{x}$ the variables + occurring in $\vec{t}$. This command generates and stocks + the inversion lemma for the sort \sort~ corresponding to the instance + $(\vec{x}:\vec{T})(I~\vec{t})$ with the name \ident~ in the {\bf + global} environment. When applied it is equivalent to have + inverted the instance with the tactic {\tt Inversion\_clear}. + + + For example, to generate the inversion lemma for the instance + \texttt{(Le (S n) m)} and the sort \texttt{Prop} we do: +\begin{coq_example} +Derive Inversion_clear leminv with (n,m:nat)(Le (S n) m) Sort Prop. +\end{coq_example} + +Let us inspect the type of the generated lemma: +\begin{coq_example} +Check leminv. +\end{coq_example} + + + +\end{itemize} + +%\variants +%\begin{enumerate} +%\item \verb+Derive Inversion_clear+ \ident$_1$ \ident$_2$ \\ +%\index{Derive Inversion_clear@{\tt Derive Inversion\_clear}} +% Let \ident$_1$ have type $(I~\vec{t})$ in the local context ($I$ +% an inductive predicate). Then, this command has the same semantics +% as \verb+Derive Inversion_clear+ \ident$_2$~ \verb+with+ +% $(\vec{x}:\vec{T})(I~\vec{t})$ \verb+Sort Prop+ where $\vec{x}$ are the free +% variables of $(I~\vec{t})$ declared in the local context (variables +% of the global context are considered as constants). +%\item \verb+Derive Inversion+ \ident$_1$~ \ident$_2$~\\ +%\index{Derive Inversion@{\tt Derive Inversion}} +% Analogous to the previous command. +%\item \verb+Derive Inversion+ $num$ \ident~ \ident~ \\ +%\index{Derive Inversion@{\tt Derive Inversion}} +% This command behaves as \verb+Derive Inversion+ \ident~ {\it +% namehyp} performed on the goal number $num$. +% +%\item \verb+Derive Inversion_clear+ $num$ \ident~ \ident~ \\ +%\index{Derive Inversion_clear@{\tt Derive Inversion\_clear}} +% This command behaves as \verb+Derive Inversion_clear+ \ident~ +% \ident~ performed on the goal number $num$. +%\end{enumerate} + + + +A derived inversion lemma is adequate for inverting the instance +with which it was generated, \texttt{Derive} applied to +different instances yields different lemmas. In general, if we generate +the inversion lemma with +an instance $(\vec{x}:\vec{T})(I~\vec{t})$ and a sort $s$, the inversion lemma will +expect a predicate of type $(\vec{x}:\vec{T})s$ as first argument. \\ + +\begin{Variant} +\item \texttt{Derive Inversion} \ident~ \texttt{with} + $(\vec{x}:\vec{T})(I~\vec{t})$ \texttt{Sort} \sort\\ +\index{Derive Inversion...with@{\tt Derive Inversion...with}} + Analogous of \texttt{Derive Inversion\_clear .. with ..} but + when applied it is equivalent to having + inverted the instance with the tactic \texttt{Inversion}. +\end{Variant} + +\subsection{The dependent case} +\begin{itemize} +\item \texttt{Derive Dependent Inversion\_clear} \ident~ \texttt{with} + $(\vec{x}:\vec{T})(I~\vec{t})$ \texttt{Sort} \sort~ \\ +\index{Derive Dependent Inversion\_clear...with@{\tt Derive Dependent Inversion\_clear...with}} + Let $I$ be an inductive predicate. This command generates and stocks + the dependent inversion lemma for the sort \sort~ corresponding to the instance + $(\vec{x}:\vec{T})(I~\vec{t})$ with the name \ident~ in the {\bf + global} environment. When applied it is equivalent to having + inverted the instance with the tactic \texttt{Dependent Inversion\_clear}. +\end{itemize} + +\begin{coq_example} +Derive Dependent Inversion_clear leminv_dep + with (n,m:nat)(Le (S n) m) Sort Prop. +\end{coq_example} + +\begin{coq_example} +Check leminv_dep. +\end{coq_example} + +\begin{Variants} +\item \texttt{Derive Dependent Inversion} \ident~ \texttt{with} + $(\vec{x}:\vec{T})(I~\vec{t})$ \texttt{Sort} \sort~ \\ +\index{Derive Dependent Inversion...with@{\tt Derive Dependent Inversion...with}} + Analogous to \texttt{Derive Dependent Inversion\_clear}, but when + applied it is equivalent to having + inverted the instance with the tactic \texttt{Dependent Inversion}. + +\end{Variants} + +\section{Using already defined inversion lemmas} +\label{inversion_using} +\begin{itemize} +\item \texttt{Inversion} \ident \texttt{ using} \ident$'$ \\ +\index{Inversion...using@{\tt Inversion...using}} + Let \ident~ have type $(I~\vec{t})$ ($I$ an inductive + predicate) in the local context, and \ident$'$ be a (dependent) inversion + lemma. Then, this tactic refines the current goal with the specified + lemma. + + +\begin{coq_eval} +Abort. +\end{coq_eval} + +\begin{coq_example} +Show. +\end{coq_example} +\begin{coq_example} +Inversion H using leminv. +\end{coq_example} + + +\end{itemize} +\variant +\begin{enumerate} +\item \texttt{Inversion} \ident~ \texttt{using} \ident$'$ \texttt{in} \ident$_1$\ldots \ident$_n$\\ +\index{Inversion...using...in@{\tt Inversion...using...in}} +This tactic behaves as generalizing \ident$_1$\ldots \ident$_n$, +then doing \texttt{Use Inversion} \ident~\ident$'$. +\end{enumerate} + +\section{\tt Scheme ...}\index{Scheme@{\tt Scheme}}\label{Scheme} +\label{scheme} +The {\tt Scheme} command is a high-level tool for generating +automatically (possibly mutual) induction principles for given types +and sorts. Its syntax follows the schema : + +\noindent +{\tt Scheme {\ident$_1$} := Induction for \term$_1$ Sort {\sort$_1$} \\ + with\\ + \mbox{}\hspace{0.1cm} .. \\ + with {\ident$_m$} := Induction for {\term$_m$} Sort + {\sort$_m$}}\\ +\term$_1$ \ldots \term$_m$ are different inductive types belonging to +the same package of mutual inductive definitions. This command +generates {\ident$_1$}\ldots{\ident$_m$} to be mutually recursive +definitions. Each term {\ident$_i$} proves a general principle +of mutual induction for objects in type {\term$_i$}. + +\Example +The definition of principle of mutual induction for {\tt tree} and +{\tt forest} over the sort {\tt Set} is defined by the command: +\begin{coq_eval} +Restore State Initial. +Variables A,B:Set. +Mutual Inductive tree : Set := node : A -> forest -> tree +with forest : Set := leaf : B -> forest + | cons : tree -> forest -> forest. +\end{coq_eval} +\begin{coq_example*} +Scheme tree_forest_rec := Induction for tree Sort Set +with forest_tree_rec := Induction for forest Sort Set. +\end{coq_example*} +You may now look at the type of {\tt tree\_forest\_rec} : +\begin{coq_example} +Check tree_forest_rec. +\end{coq_example} +This principle involves two different predicates for {\tt trees} and +{\tt forests}; it also has three premises each one corresponding to a +constructor of one of the inductive definitions. + +The principle {\tt tree\_forest\_rec} shares exactly the same +premises, only the conclusion now refers to the property of forests. +\begin{coq_example} +Check forest_tree_rec. +\end{coq_example} + +\begin{Variant} +\item {\tt Scheme {\ident$_1$} := Minimality for \term$_1$ Sort {\sort$_1$} \\ + with\\ + \mbox{}\hspace{0.1cm} .. \\ + with {\ident$_m$} := Minimality for {\term$_m$} Sort + {\sort$_m$}}\\ +Same as before but defines a non-dependent elimination principle more +natural in case of inductively defined relations. +\end{Variant} + +\Example +With the predicates {\tt odd} and {\tt even} inductively defined as: +\begin{coq_eval} +Restore State Initial. +\end{coq_eval} +\begin{coq_example*} +Mutual Inductive odd : nat->Prop := + oddS : (n:nat)(even n)->(odd (S n)) +with even : nat -> Prop := + evenO : (even O) + | evenS : (n:nat)(odd n)->(even (S n)). +\end{coq_example*} +The following command generates a powerful elimination +principle: +\begin{coq_example*} +Scheme odd_even := Minimality for odd Sort Prop +with even_odd := Minimality for even Sort Prop. +\end{coq_example*} +The type of {\tt odd\_even} for instance will be: +\begin{coq_example} +Check odd_even. +\end{coq_example} +The type of {\tt even\_odd} shares the same premises but the +conclusion is {\tt (n:nat)(even n)->(Q n)}. + + + +%\end{document} + +% $Id$ diff --git a/doc/RefMan-int.tex b/doc/RefMan-int.tex new file mode 100755 index 000000000..d874f7cdb --- /dev/null +++ b/doc/RefMan-int.tex @@ -0,0 +1,127 @@ +\setheaders{Introduction} +\chapter*{Introduction} + +This document is the Reference Manual of version V6.2.4 of the \Coq\ +proof assistant. A companion volume, the \Coq\ Tutorial, is provided +for the beginners. It is advised to read the Tutorial first. + +The system \Coq\ is designed to write formal specifications, +programs and to verify that programs are correct with respect to their +specification. It provides a specification language named \gallina. Terms of +\gallina\ can represent programs as well as properties of these +programs and proofs of these properties. Using the so-called +\textit{Curry-Howard isomorphism}, programs, properties and proofs are +formalized the same +language called \textit{Calculus of Inductive Constructions}, that is +a $\lambda$-calculus with a rich type system. +All logical judgments in \Coq\ are typing judgments. The very heart of the Coq +system is the type-checking algorithm that checks the correctness of +proofs, in other words that checks that a program complies to its +specification. \Coq\ also provides an interactive proof assistant to +build proofs using specific programs called \textit{tactics}. + +All services of the \Coq\ proof assistant are accessible by +interpretation of a command language called \textit{the vernacular}. + +\Coq\ has an interactive mode in which commands are interpreted as the +user types them in from the keyboard and a compiled mode where +commands are processed from a file. Other modes of interaction with +\Coq\ are possible, through an emacs shell window, or through a +customized interface with the Centaur environment (CTCoq). These +facilities are not documented here. + +\begin{itemize} +\item The interactive mode may be used as a debugging mode in which + the user can develop his theories and proofs step by step, + backtracking if needed and so on. The interactive mode is run with + the {\tt coqtop} command from the operating system (which we shall + assume to be some variety of UNIX in the rest of this document). +\item The compiled mode acts as a proof checker taking a file + containing a whole development in order to ensure its correctness. + Moreover, \Coq's compiler provides an output file containing a + compact representation of its input. The compiled mode is run with + the {\tt coqc} command from the operating system. Its use is + documented in chapter \ref{Addoc-coqc}. +\end{itemize} + +\section*{How to read this book} + +This is a Reference Manual, not a User Manual, then it is not made for a +continuous reading. However, it has some structure that is explained +below. + +\begin{itemize} +\item The first part describes the specification language, + Gallina. The chapters \ref{Gallina} and \ref{Gallina-extension} + describe the concrete syntax as well as the meaning of programs, + theorems and proofs in the Calculus of Inductive Construction. The + chapter \ref{Theories} describes the standard library of \Coq. The + chapter \ref{Cic} is a mathematical description of the formalism. + +\item The second part describes the proof engine. It is divided in + three chapters. Chapter \ref{Vernacular-commands} presents + all commands (we call them \textit{vernacular commands}) that are not + directly related to interactive proving: requests to the environment, + complete or partial evaluation, loading and compiling files. How to + start and stop proofs, do multiple proofs in parallel is explained + in the chapter \ref{Proof-handling}. In chapter \ref{Tactics}, + all commands that realize one or more steps of the proof are + presented: we call them \textit{tactics}. + +\item The third part describes how to extend the system in two ways: + adding parsing and pretty-printing rules (chapter + \ref{Addoc-syntax}) and writing new tactics (chapter + \ref{WritingTactics}) + + +\item In the fourth part more practical tools are documented. First in + the chapter \ref{Addoc-coqc} the usage of \texttt{coqc} (batch mode) + and \texttt{coqtop} (interactive mode) with their options is + described. Then (in chapter \ref{Utilities}) + various utilities that come with the \Coq\ distribution are presented. +\end{itemize} + +At the end of the document, after the global index, the user can find +a tactic index and a vernacular command index. + +\section*{List of additionnal documentation} + +This manual contains not all the documentation the user may need about +Coq. Various informations can be found in the following documents: + +\begin{description} + +\item[Tutorial] + A companion volume to this reference manual, the \Coq\ Tutorial, is + aimed at gently introducing new users to developing proofs in \Coq\ + without assuming prior knowledge of type theory. In a second step, the + user can read also the tutorial on recursive types (document {\tt + RecTutorial.ps}). + +\item[Addendum] The fifth part (the Addendum) of the Reference Manual + is distributed as a separate document. It contains more + detailed documentation and examples about some specific aspects of the + system that may interest only certain users. It shares the indexes, + the page numbers and + the bibliography with the Reference Manual. If you see in one of the + indexes a page number that is outside the Reference Manual, it refers + to the Addendum. + +\item[Installation] A text file INSTALL that comes with the sources + explains how to install \Coq. A file UNINSTALL explains how + uninstall or move it. + +\item[The \Coq\ standard library] +A commented version of sources of the \Coq\ standard library +(including only the specifications, the proofs are removed) +is given in the additional document {\tt Library.ps}. + +\end{description} + + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/RefMan-lib.tex b/doc/RefMan-lib.tex new file mode 100755 index 000000000..6af0f55cf --- /dev/null +++ b/doc/RefMan-lib.tex @@ -0,0 +1,883 @@ +\chapter{The {\Coq} library} +\index{Theories}\label{Theories} + +The \Coq\ library is structured into three parts: + +\begin{description} +\item[The initial library:] it contains + elementary logical notions and datatypes. It constitutes the + basic state of the system directly available when running + \Coq; + +\item[The standard library:] general-purpose libraries containing + various developments of \Coq\ axiomatizations about sets, lists, + sorting, arithmetic, etc. This library comes with the system and its + modules are directly accessible through the \verb!Require! command + (see~\ref{Require}); + +\item[User contributions:] Other specification and proof developments + coming from the \Coq\ users' community. These libraries are no + longer distributed with the system. They are available by anonymous + FTP (see section \ref{Contributions}). +\end{description} + +This chapter briefly reviews these libraries. + +\section{The basic library} +\label{Prelude} + +This section lists the basic notions and results which are directly +available in the standard \Coq\ system +\footnote{These constructions are defined in the +{\tt Prelude} module in directory {\tt theories/INIT} at the {\Coq} +root directory; this includes the modules +% {\tt Core} l'inexplicable let +{\tt Logic}, +{\tt Datatypes}, +{\tt Specif}, +{\tt Peano}, +and {\tt Wf} +plus the module {\tt Logic\_Type}}. + +\subsection{Logic} \label{Logic} + +The basic library of {\Coq} comes with the definitions of standard +(intuitionistic) logical connectives (they are defined as inductive +constructions). They are equipped with an appealing syntax enriching the +(subclass {\form}) of the syntactic class {\term}. The syntax +extension +\footnote{This syntax is defined in module {\tt LogicSyntax}} + is shown on figure \ref{formulas-syntax}. + +\begin{figure} +\label{formulas-syntax} +\begin{center} +\begin{tabular}{|lclr|} +\hline +{\form} & ::= & {\tt True} & ({\tt True})\\ + & $|$ & {\tt False} & ({\tt False})\\ + & $|$ & {\verb|~|} {\form} & ({\tt not})\\ + & $|$ & {\form} {\tt /$\backslash$} {\form} & ({\tt and})\\ + & $|$ & {\form} {\tt $\backslash$/} {\form} & ({\tt or})\\ + & $|$ & {\form} {\tt ->} {\form} & (\em{primitive implication})\\ + & $|$ & {\form} {\tt <->} {\form} & ({\tt iff})\\ + & $|$ & {\tt (} {\ident} {\tt :} {\type} {\tt )} + {\form} & (\em{primitive for all})\\ + & $|$ & {\tt ( ALL} {\ident} \zeroone{{\tt :} {\specif}} {\tt |} + {\form} {\tt )} & ({\tt all})\\ + & $|$ & {\tt ( EX} {\ident} \zeroone{{\tt :} {\specif}} {\tt + |} {\form} {\tt )} & ({\tt ex})\\ + & $|$ & {\tt ( EX} {\ident} \zeroone{{\tt :} {\specif}} {\tt + |} {\form} {\tt \&} {\form} {\tt )} & ({\tt ex2})\\ + & $|$ & {\term} {\tt =} {\term} & ({\tt eq})\\ +\hline +\end{tabular} +\end{center} + +\medskip + +\noindent Remark: The implication is not defined but primitive +(it is a non-dependent product of a proposition over another proposition). +There is also a primitive universal quantification (it is a +dependent product over a proposition). The primitive universal +quantification allows both first-order and higher-order +quantification. There is no need to +use the notation {\tt ( ALL} {\ident} \zeroone{{\tt :} {\specif}} {\tt +|} {\form} {\tt )} propositions), except to have a notation dual of +the notation for first-order existential quantification. +\caption{Syntax of formulas} +\end{figure} + +\subsubsection{Propositional Connectives} \label{Connectives} +\index{Connectives} + +First, we find propositional calculus connectives: +\ttindex{True} +\ttindex{I} +\ttindex{False} +\ttindex{not} +\ttindex{and} +\ttindex{conj} +\ttindex{proj1} +\ttindex{proj2} + +\begin{coq_example*} +Inductive True : Prop := I : True. +Inductive False : Prop := . +Definition not := [A:Prop] A->False. +Inductive and [A,B:Prop] : Prop := conj : A -> B -> A/\B. +Section Projections. +Variables A,B : Prop. +Theorem proj1 : A/\B -> A. +Theorem proj2 : A/\B -> B. +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +\end{coq_eval} +\ttindex{or} +\ttindex{or\_introl} +\ttindex{or\_intror} +\ttindex{iff} +\ttindex{IF} +\begin{coq_example*} +End Projections. +Inductive or [A,B:Prop] : Prop + := or_introl : A -> A\/B + | or_intror : B -> A\/B. +Definition iff := [P,Q:Prop] (P->Q) /\ (Q->P). +Definition IF := [P,Q,R:Prop] (P/\Q) \/ (~P/\R). +\end{coq_example*} + +\subsubsection{Quantifiers} \label{Quantifiers} +\index{Quantifiers} + +Then we find first-order quantifiers: +\ttindex{all} +\ttindex{All} +\ttindex{ex} +\ttindex{Ex} +\ttindex{EX} +\ttindex{ex\_intro} +\ttindex{ex2} +\ttindex{Ex2} +\ttindex{ex\_intro2} + +\begin{coq_example*} +Definition all := [A:Set][P:A->Prop](x:A)(P x). +Inductive ex [A:Set;P:A->Prop] : Prop + := ex_intro : (x:A)(P x)->(ex A P). +Inductive ex2 [A:Set;P,Q:A->Prop] : Prop + := ex_intro2 : (x:A)(P x)->(Q x)->(ex2 A P Q). +\end{coq_example*} + +The following abbreviations are allowed: +\begin{center} + \begin{tabular}[h]{|l|r|} + \hline + \verb+(ALL x:A | P)+ & \verb+(all A [x:A]P)+ \\ + \verb+(ALL x | P)+ & \verb+(all A [x:A]P)+ \\ + \verb+(EX x:A | P)+ & \verb+(ex A [x:A]P)+ \\ + \verb+(EX x | P)+ & \verb+(ex A [x:A]P)+ \\ + \verb+(EX x:A | P & Q)+ & \verb+(ex2 A [x:A]P [x:A]Q)+ \\ + \verb+(EX x | P & Q)+ & \verb+(ex2 A [x:A]P [x:A]Q)+ \\ + \hline + \end{tabular} +\end{center} + +The type annotation \texttt{:A} can be omitted when \texttt{A} can be +synthesized by the system. + +\subsubsection{Equality} \label{Equality} +\index{Equality} + +Then, we find equality, defined as an inductive relation. That is, +given a \verb:Set: \verb:A: and an \verb:x: of type \verb:A:, the +predicate \verb:(eq A x): is the smallest which contains \verb:x:. +This definition, due to Christine Paulin-Mohring, is equivalent to +define \verb:eq: as the smallest reflexive relation, and it is also +equivalent to Leibniz' equality. + +\ttindex{eq} +\ttindex{refl\_equal} + +\begin{coq_example*} +Inductive eq [A:Set;x:A] : A->Prop + := refl_equal : (eq A x x). +\end{coq_example*} + +\subsubsection{Lemmas} \label{PreludeLemmas} +Finally, a few easy lemmas are provided. + +\ttindex{absurd} + +\begin{coq_example*} +Theorem absurd : (A:Prop)(C:Prop) A -> ~A -> C. +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} +\ttindex{sym\_equal} +\ttindex{trans\_equal} +\ttindex{f\_equal} +\ttindex{sym\_not\_equal} +\begin{coq_example*} +Section equality. + Variable A,B : Set. + Variable f : A->B. + Variable x,y,z : A. + Theorem sym_equal : x=y -> y=x. + Theorem trans_equal : x=y -> y=z -> x=z. + Theorem f_equal : x=y -> (f x)=(f y). + Theorem sym_not_equal : ~(x=y) -> ~(y=x). +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +Abort. +Abort. +\end{coq_eval} +\ttindex{eq\_ind\_r} +\ttindex{eq\_rec\_r} +\begin{coq_example*} +End equality. +Definition eq_ind_r : (A:Set)(x:A)(P:A->Prop)(P x)->(y:A)y=x->(P y). +Definition eq_rec_r : (A:Set)(x:A)(P:A->Set)(P x)->(y:A)y=x->(P y). +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +\end{coq_eval} +\begin{coq_example*} +Immediate sym_equal sym_not_equal. +\end{coq_example*} + +\subsection{Datatypes} \label{Datatypes} + +In the basic library, we find the definition\footnote{They are in {\tt +Datatypes.v}} +of the basic data-types of programming, +again defined as inductive constructions over the sort +\verb:Set:. Some of them come with a special syntax shown on figure +\ref{specif-syntax}. + +\subsubsection{Programming} \label{Programming} +\index{Programming} +\index{Datatypes} + +\ttindex{unit} +\ttindex{tt} +\ttindex{bool} +\ttindex{true} +\ttindex{false} +\ttindex{nat} +\ttindex{O} +\ttindex{S} + +\begin{coq_example*} +Inductive unit : Set := tt : unit. +Inductive bool : Set := true : bool + | false : bool. +Inductive nat : Set := O : nat + | S : nat->nat. +\end{coq_example*} + +Note that zero is the letter \verb:O:, and {\sl not} the numeral +\verb:0:. + +We then define the disjoint sum of \verb:A+B: of two sets \verb:A: and +\verb:B:, and their product \verb:A*B:. +\ttindex{sum} +\ttindex{A+B} +\ttindex{+} +\ttindex{inl} +\ttindex{inr} +\ttindex{prod} +\ttindex{A*B} +\ttindex{*} +\ttindex{pair} +\ttindex{fst} +\ttindex{snd} +\ttindex{Fst} +\ttindex{Snd} + +\begin{coq_example*} +Inductive sum [A,B:Set] : Set + := inl : A -> A+B + | inr : B -> A+B. +Inductive prod [A,B:Set] : Set := pair : A -> B -> A*B. +Section projections. + Variables A,B:Set. + Definition fst := [H:A*B] Cases H of (x,y) => x end. + Definition snd := [H:A*B] Cases H of (x,y) => y end. +End projections. +Syntactic Definition Fst := (fst ? ?). +Syntactic Definition Snd := (snd ? ?). +\end{coq_example*} + +\subsection{Specification} + +The following notions\footnote{They are defined in module {\tt +Specif.v}} allows to build new datatypes and specifications. +They are available with the syntax shown on +figure \ref{specif-syntax}\footnote{This syntax can be found in the module +{\tt SpecifSyntax.v}}. + +For instance, given \verb|A:Set| and \verb|P:A->Prop|, the construct +\verb+{x:A | (P x)}+ (in abstract syntax \verb+(sig A P)+) is a +\verb:Set:. We may build elements of this set as \verb:(exist x p): +whenever we have a witness \verb|x:A| with its justification +\verb|p:(P x)|. + +From such a \verb:(exist x p): we may in turn extract its witness +\verb|x:A| (using an elimination construct such as \verb:Cases:) but +{\sl not} its justification, which stays hidden, like in an abstract +data type. In technical terms, one says that \verb:sig: is a ``weak +(dependent) sum''. A variant \verb:sig2: with two predicates is also +provided. + +\index{\{x:A "| (P x)\}} +\index{"|} +\ttindex{sig} +\ttindex{exist} +\ttindex{sig2} +\ttindex{exist2} + +\begin{coq_example*} +Inductive sig [A:Set;P:A->Prop] : Set + := exist : (x:A)(P x) -> (sig A P). +Inductive sig2 [A:Set;P,Q:A->Prop] : Set + := exist2 : (x:A)(P x) -> (Q x) -> (sig2 A P Q). +\end{coq_example*} + +A ``strong (dependent) sum'' \verb+{x:A & (P x)}+ may be also defined, +when the predicate \verb:P: is now defined as a \verb:Set: +constructor. + +\ttindex{\{x:A \& (P x)\}} +\ttindex{\&} +\ttindex{sigS} +\ttindex{existS} +\ttindex{projS1} +\ttindex{projS2} +\ttindex{sigS2} +\ttindex{existS2} + +\begin{coq_example*} +Inductive sigS [A:Set;P:A->Set] : Set + := existS : (x:A)(P x) -> (sigS A P). +Section projections. + Variable A:Set. + Variable P:A->Set. + Definition projS1 := [H:(sigS A P)] let (x,h) = H in x. + Definition projS2 := [H:(sigS A P)]<[H:(sigS A P)](P (projS1 H))> + let (x,h) = H in h. +End projections. +Inductive sigS2 [A:Set;P,Q:A->Set] : Set + := existS2 : (x:A)(P x) -> (Q x) -> (sigS2 A P Q). +\end{coq_example*} + +A related non-dependent construct is the constructive sum +\verb"{A}+{B}" of two propositions \verb:A: and \verb:B:. +\label{sumbool} +\ttindex{sumbool} +\ttindex{left} +\ttindex{right} +\ttindex{\{A\}+\{B\}} + +\begin{coq_example*} +Inductive sumbool [A,B:Prop] : Set + := left : A -> ({A}+{B}) + | right : B -> ({A}+{B}). +\end{coq_example*} + +This \verb"sumbool" construct may be used as a kind of indexed boolean +data type. An intermediate between \verb"sumbool" and \verb"sum" is +the mixed \verb"sumor" which combines \verb"A:Set" and \verb"B:Prop" +in the \verb"Set" \verb"A+{B}". +\ttindex{sumor} +\ttindex{inleft} +\ttindex{inright} +\ttindex{A+\{B\}} + +\begin{coq_example*} +Inductive sumor [A:Set;B:Prop] : Set + := inleft : A -> (A+{B}) + | inright : B -> (A+{B}). +\end{coq_example*} + +\begin{figure} +\label{specif-syntax} +\begin{center} +\begin{tabular}{|lclr|} +\hline +{\specif} & ::= & {\specif} {\tt *} {\specif} & ({\tt prod})\\ + & $|$ & {\specif} {\tt +} {\specif} & ({\tt sum})\\ + & $|$ & {\specif} {\tt + \{} {\specif} {\tt \}} & ({\tt sumor})\\ + & $|$ & {\tt \{} {\specif} {\tt \} + \{} {\specif} {\tt \}} & + ({\tt sumbool})\\ + & $|$ & {\tt \{} {\ident} {\tt :} {\specif} {\tt |} {\form} {\tt \}} + & ({\tt sig})\\ + & $|$ & {\tt \{} {\ident} {\tt :} {\specif} {\tt |} {\form} {\tt \&} + {\form} {\tt \}} & ({\tt sig2})\\ + & $|$ & {\tt \{} {\ident} {\tt :} {\specif} {\tt \&} {\specif} {\tt + \}} & ({\tt sigS})\\ + & $|$ & {\tt \{} {\ident} {\tt :} {\specif} {\tt \&} {\specif} {\tt + \&} {\specif} {\tt \}} & ({\tt sigS2})\\ + & & & \\ +{\term} & ::= & {\tt (} {\term} {\tt ,} {\term} {\tt )} & ({\tt pair})\\ +\hline +\end{tabular} +\caption{Syntax of datatypes and specifications} +\end{center} +\end{figure} + +We may define variants of the axiom of choice, like in Martin-Löf's +Intuitionistic Type Theory. +\ttindex{Choice} +\ttindex{Choice2} +\ttindex{bool\_choice} + +\begin{coq_example*} +Lemma Choice : (S,S':Set)(R:S->S'->Prop)((x:S){y:S'|(R x y)}) + -> {f:S->S'|(z:S)(R z (f z))}. +Lemma Choice2 : (S,S':Set)(R:S->S'->Set)((x:S){y:S' & (R x y)}) + -> {f:S->S' & (z:S)(R z (f z))}. +Lemma bool_choice : (S:Set)(R1,R2:S->Prop)((x:S){(R1 x)}+{(R2 x)}) -> + {f:S->bool | (x:S)( ((f x)=true /\ (R1 x)) + \/ ((f x)=false /\ (R2 x)))}. +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +Abort. +\end{coq_eval} + +The next construct builds a sum between a data type \verb|A:Set| and +an exceptional value encoding errors: + +\ttindex{Exc} +\ttindex{value} +\ttindex{error} + +\begin{coq_example*} +Inductive Exc [A:Set] : Set := value : A->(Exc A) + | error : (Exc A). +\end{coq_example*} + + +This module ends with one axiom and theorems, +relating the sorts \verb:Set: and +\verb:Prop: in a way which is consistent with the realizability +interpretation. +\ttindex{False\_rec} +\ttindex{eq\_rec} +\ttindex{Except} +\ttindex{absurd\_set} +\ttindex{and\_rec} + +\begin{coq_example*} +Axiom False_rec : (P:Set)False->P. +Definition except := False_rec. +Syntactic Definition Except := (except ?). +Theorem absurd_set : (A:Prop)(C:Set)A->(~A)->C. +Theorem and_rec : (A,B:Prop)(C:Set)(A->B->C)->(A/\B)->C. +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +\end{coq_eval} + +\subsection{Basic Arithmetics} + +The basic library includes a few elementary properties of natural numbers, +together with the definitions of predecessor, addition and +multiplication\footnote{This is in module {\tt Peano.v}}. +\ttindex{eq\_S} +\ttindex{pred} +\ttindex{pred\_Sn} +\ttindex{eq\_add\_S} +\ttindex{not\_eq\_S} +\ttindex{IsSucc} +\ttindex{O\_S} +\ttindex{n\_Sn} +\ttindex{plus} +\ttindex{plus\_n\_O} +\ttindex{plus\_n\_Sm} +\ttindex{mult} +\ttindex{mult\_n\_O} +\ttindex{mult\_n\_Sm} + +\begin{coq_example*} +Theorem eq_S : (n,m:nat) n=m -> (S n)=(S m). +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} +\begin{coq_example*} +Definition pred : nat->nat + := [n:nat](<nat>Cases n of O => O + | (S u) => u end). +Theorem pred_Sn : (m:nat) m=(pred (S m)). +Theorem eq_add_S : (n,m:nat) (S n)=(S m) -> n=m. +Immediate eq_add_S. +Theorem not_eq_S : (n,m:nat) ~(n=m) -> ~((S n)=(S m)). +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +Abort. +\end{coq_eval} +\begin{coq_example*} +Definition IsSucc : nat->Prop + := [n:nat](<Prop>Cases n of O => False + | (S p) => True end). +Theorem O_S : (n:nat) ~(O=(S n)). +Theorem n_Sn : (n:nat) ~(n=(S n)). +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +\end{coq_eval} +\begin{coq_example*} +Fixpoint plus [n:nat] : nat -> nat := + [m:nat](<nat>Cases n of + O => m + | (S p) => (S (plus p m)) end). +Lemma plus_n_O : (n:nat) n=(plus n O). +Lemma plus_n_Sm : (n,m:nat) (S (plus n m))=(plus n (S m)). +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +\end{coq_eval} +\begin{coq_example*} +Fixpoint mult [n:nat] : nat -> nat := + [m:nat](<nat> Cases n of O => O + | (S p) => (plus m (mult p m)) end). +Lemma mult_n_O : (n:nat) O=(mult n O). +Lemma mult_n_Sm : (n,m:nat) (plus (mult n m) n)=(mult n (S m)). +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +\end{coq_eval} + +Finally, it gives the definition of the usual orderings \verb:le:, +\verb:lt:, \verb:ge:, and \verb:gt:. +\ttindex{le} +\ttindex{le\_n} +\ttindex{le\_S} +\ttindex{lt} +\ttindex{ge} +\ttindex{gt} + +\begin{coq_example*} +Inductive le [n:nat] : nat -> Prop + := le_n : (le n n) + | le_S : (m:nat)(le n m)->(le n (S m)). +Definition lt := [n,m:nat](le (S n) m). +Definition ge := [n,m:nat](le m n). +Definition gt := [n,m:nat](lt m n). +\end{coq_example*} + +Properties of these relations are not initially known, but may be +required by the user from modules \verb:Le: and \verb:Lt:. Finally, +\verb:Peano: gives some lemmas allowing pattern-matching, and a double +induction principle. + +\ttindex{nat\_case} +\ttindex{nat\_double\_ind} + +\begin{coq_example*} +Theorem nat_case : (n:nat)(P:nat->Prop)(P O)->((m:nat)(P (S m)))->(P n). +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} +\begin{coq_example*} +Theorem nat_double_ind : (R:nat->nat->Prop) + ((n:nat)(R O n)) -> ((n:nat)(R (S n) O)) + -> ((n,m:nat)(R n m)->(R (S n) (S m))) + -> (n,m:nat)(R n m). +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\subsection{Well-founded recursion} + +The basic library contains the basics of well-founded recursion and +well-founded induction\footnote{This is defined in module {\tt Wf.v}}. +\index{Well foundedness} +\index{Recursion} +\index{Well founded induction} +\ttindex{Acc} +\ttindex{Acc\_inv} +\ttindex{Acc\_rec} +\ttindex{well\_founded} + +\begin{coq_example*} +Chapter Well_founded. +Variable A : Set. +Variable R : A -> A -> Prop. +Inductive Acc : A -> Prop + := Acc_intro : (x:A)((y:A)(R y x)->(Acc y))->(Acc x). +Lemma Acc_inv : (x:A)(Acc x) -> (y:A)(R y x) -> (Acc y). +\end{coq_example*} +\begin{coq_eval} +Destruct 1; Trivial. +Defined. +\end{coq_eval} +\begin{coq_example*} +Section AccRec. +Variable P : A -> Set. +Variable F : (x:A)((y:A)(R y x)->(Acc y))->((y:A)(R y x)->(P y))->(P x). +Fixpoint Acc_rec [x:A;a:(Acc x)] : (P x) + := (F x (Acc_inv x a) [y:A][h:(R y x)](Acc_rec y (Acc_inv x a y h))). +End AccRec. +Definition well_founded := (a:A)(Acc a). +Theorem well_founded_induction : + well_founded -> + (P:A->Set)((x:A)((y:A)(R y x)->(P y))->(P x))->(a:A)(P a). +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} +\begin{coq_example*} +End Well_founded. +\end{coq_example*} +\begin{coq_example*} + Section Wf_inductor. +Variable A:Set. +Variable R:A->A->Prop. +Theorem well_founded_ind : + (well_founded A R) -> + (P:A->Prop)((x:A)((y:A)(R y x)->(P y))->(P x))->(a:A)(P a). +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} +\begin{coq_example*} +End Wf_inductor. +\end{coq_example*} + + +\subsection{Accessing the {\Type} level} + +The basic library includes the definitions\footnote{This is in module +{\tt Logic\_Type.v}} of logical quantifiers axiomatized at the +\verb:Type: level. + +\ttindex{allT} +\ttindex{AllT} +\ttindex{inst} +\ttindex{gen} +\ttindex{exT} +\ttindex{ExT} +\ttindex{EXT} +\ttindex{exT\_intro} +\ttindex{ExT2} +\ttindex{exT2} +\ttindex{EmptyT} +\ttindex{UnitT} +\ttindex{notT} + +\begin{coq_example*} +Definition allT := [A:Type][P:A->Prop](x:A)(P x). + +Section universal_quantification. +Variable A : Type. +Variable P : A->Prop. +Theorem inst : (x:A)(ALLT x | (P x))->(P x). +Theorem gen : (B:Prop)(f:(y:A)B->(P y))B->(allT ? P). +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +\end{coq_eval} +\begin{coq_example*} +End universal_quantification. +Inductive exT [A:Type;P:A->Prop] : Prop + := exT_intro : (x:A)(P x)->(exT A P). + +Inductive exT2 [A:Type;P,Q:A->Prop] : Prop + := exT_intro2 : (x:A)(P x)->(Q x)->(exT2 A P Q). +\end{coq_example*} + +It defines also Leibniz equality \verb:x==y: when \verb:x: and +\verb:y: belong to \verb+A:Type+. +\ttindex{eqT} +\ttindex{refl\_eqT} +\ttindex{sum\_eqT} +\ttindex{sym\_not\_eqT} +\ttindex{trans\_eqT} +\ttindex{congr\_eqT} +\ttindex{eqT\_ind\_r} +\ttindex{eqT\_rec\_r} + +\begin{coq_example*} +Inductive eqT [A:Type;x:A] : A -> Prop + := refl_eqT : (eqT A x x). +Section Equality_is_a_congruence. +Variables A,B : Type. +Variable f : A->B. + Variable x,y,z : A. + Lemma sym_eqT : (x==y) -> (y==x). + Lemma trans_eqT : (x==y) -> (y==z) -> (x==z). + Lemma congr_eqT : (x==y)->((f x)==(f y)). +\end{coq_example*} +\begin{coq_eval} +Abort. +Abort. +Abort. +\end{coq_eval} +\begin{coq_example*} +End Equality_is_a_congruence. +Immediate sym_eqT sym_not_eqT. +Definition eqT_ind_r: (A:Type)(x:A)(P:A->Prop)(P x)->(y:A)y==x -> (P y). +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} + +The figure \ref{formulas-syntax-type} presents the syntactic notations +corresponding to the main definitions +\footnote{This syntax is defined in module {\tt Logic\_TypeSyntax}} + +\begin{figure} +\label{formulas-syntax-type} +\begin{center} +\begin{tabular}{|lclr|} +\hline +{\form} & ::= & {\tt ( ALLT} {\ident} \zeroone{{\tt :} {\specif}} {\tt |} + {\form} {\tt )} & ({\tt allT})\\ + & $|$ & {\tt ( EXT} {\ident} \zeroone{{\tt :} {\specif}} {\tt + |} {\form} {\tt )} & ({\tt exT})\\ + & $|$ & {\tt ( EXT} {\ident} \zeroone{{\tt :} {\specif}} {\tt + |} {\form} {\tt \&} {\form} {\tt )} & ({\tt exT2})\\ + & $|$ & {\term} {\tt ==} {\term} & ({\tt eqT})\\ +\hline +\end{tabular} +\end{center} +\caption{Syntax of first-order formulas in the type universe} +\end{figure} + +At the end, it defines datatypes at the {\Type} level. + +\begin{coq_example*} +Inductive EmptyT: Type :=. +Inductive UnitT : Type := IT : UnitT. +Definition notT := [A:Type] A->EmptyT. + +Inductive identityT [A:Type; a:A] : A->Type := + refl_identityT : (identityT A a a). +\end{coq_example*} + + +\section{The standard library} + +\subsection{Survey} + +The rest of the standard library is structured into the following +subdirectories: + +\begin{tabular}{lp{12cm}} + {\bf LOGIC} & Classical logic and dependent equality \\ + {\bf ARITH} & Basic Peano arithmetic \\ + {\bf ZARITH} & Basic integer arithmetic \\ + {\bf BOOL} & Booleans (basic functions and results) \\ + {\bf LISTS} & Monomorphic and polymorphic lists (basic functions and + results), Streams (infinite sequences defined with co-inductive + types) \\ + {\bf SETS} & Sets (classical, constructive, finite, infinite, power set, + etc.) \\ + {\bf RELATIONS} & Relations (definitions and basic results). There is + a subdirectory about well-founded relations ({\bf WELLFOUNDED}) \\ + {\bf SORTING} & Various sorting algorithms \\ + {\bf REALS} & Axiomatization of Real Numbers (classical, basic functions + and results, integer part and fractional part, + requires the \textbf{ZARITH} library) +\end{tabular} +\medskip + +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 \verb!Require! (see +chapter~\ref{Other-commands}). + +The different modules of the \Coq\ standard library are described in the +additional document \verb!Library.dvi!. They are also accessible on the WWW +through the \Coq\ homepage +\footnote{\texttt{http://coq.inria.fr}}. + +\subsection{Notations for integer arithmetics} +\index{Arithmetical notations} + +On figure \ref{zarith-syntax} is described the syntax of expressions +for integer arithmetics. It is provided by requiring the module {\tt ZArith}. + +\ttindex{+} +\ttindex{*} +\ttindex{-} + +The {\tt +} and {\tt -} binary operators bind less than the {\tt *} operator +which binds less than the {\tt |}~...~{\tt |} and {\tt -} unary +operators which bind less than the others constructions. +All the binary operators are left associative. The {\tt [}~...~{\tt ]} +allows to escape the {\zarith} grammar. + +\begin{figure} +\begin{center} +\begin{tabular}{|lcl|} +\hline +{\form} & ::= & {\tt `} {\zarithformula} {\tt `}\\ + & & \\ +{\term} & ::= & {\tt `} {\zarith} {\tt `}\\ + & & \\ +{\zarithformula} & ::= & {\zarith} {\tt =} {\zarith} \\ + & $|$ & {\zarith} {\tt <=} {\zarith} \\ + & $|$ & {\zarith} {\tt <} {\zarith} \\ + & $|$ & {\zarith} {\tt >=} {\zarith} \\ + & $|$ & {\zarith} {\tt >} {\zarith} \\ + & $|$ & {\zarith} {\tt =} {\zarith} {\tt =} {\zarith} \\ + & $|$ & {\zarith} {\tt <=} {\zarith} {\tt <=} {\zarith} \\ + & $|$ & {\zarith} {\tt <=} {\zarith} {\tt <} {\zarith} \\ + & $|$ & {\zarith} {\tt <} {\zarith} {\tt <=} {\zarith} \\ + & $|$ & {\zarith} {\tt <} {\zarith} {\tt <} {\zarith} \\ + & $|$ & {\zarith} {\tt <>} {\zarith} \\ + & $|$ & {\zarith} {\tt ?} {\tt =} {\zarith} \\ + & & \\ +{\zarith} & ::= & {\zarith} {\tt +} {\zarith} \\ + & $|$ & {\zarith} {\tt -} {\zarith} \\ + & $|$ & {\zarith} {\tt *} {\zarith} \\ + & $|$ & {\tt |} {\zarith} {\tt |} \\ + & $|$ & {\tt -} {\zarith} \\ + & $|$ & {\ident} \\ + & $|$ & {\tt [} {\term} {\tt ]} \\ + & $|$ & {\tt (} \nelist{\zarith}{} {\tt )} \\ + & $|$ & {\tt (} \nelist{\zarith}{,} {\tt )} \\ + & $|$ & {\integer} \\ +\hline +\end{tabular} +\end{center} +\label{zarith-syntax} +\caption{Syntax of expressions in integer arithmetics} +\end{figure} + +\subsection{Notations for Peano's arithmetic (\texttt{nat})} +\index{Peano's arithmetic notations} + +After having required the module \texttt{Arith}, the user can type the +naturals using decimal notation. That is he can write \texttt{(3)} +for \texttt{(S (S (S O)))}. The number must be between parentheses. +This works also in the left hand side of a \texttt{Cases} expression +(see for example section \ref{Refine-example}). + +\section{Users' contributions} +\index{Contributions} +\label{Contributions} + +Numerous users' contributions have been collected and are available on +the WWW at the following address: \verb!pauillac.inria.fr/coq/contribs!. +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. +There is a small search engine to look for keywords in all contributions. +You will also find informations on how to submit a new contribution. + +The users' contributions may also be obtained by anonymous FTP from site +\verb:ftp.inria.fr:, in directory \verb:INRIA/coq/: and +searchable on-line at + +\begin{quotation} + \texttt{http://coq.inria.fr/contribs-eng.html} +\end{quotation} + +% $Id$ + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/doc/RefMan-oth.tex b/doc/RefMan-oth.tex new file mode 100644 index 000000000..88f460497 --- /dev/null +++ b/doc/RefMan-oth.tex @@ -0,0 +1,613 @@ +\chapter{Vernacular commands} +\label{Vernacular-commands} +\label{Other-commands} + +\section{Displaying} + +\subsection{\tt Print {\ident}.}\comindex{Print} +This command displays on the screen informations about the declared or +defined object {\ident}. + +\begin{ErrMsgs} +\item {\ident} \errindex{not declared} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Print Proof {\ident}.}\comindex{Print Proof}\\ +In case \ident\ corresponds to an opaque theorem defined in a section, +it is stored on a special unprintable form and displayed as +{\tt <recipe>}. {\tt Print Proof} forces the printable form of \ident\ +to be computed and displays it. +\end{Variants} + +\subsection{\tt Print All.}\comindex{Print All} +This command displays informations about the current state of the +environment, including sections and modules. + +\begin{Variants} +\item {\tt Inspect \num.}\comindex{Inspect}\\ +This command displays the {\num} last objects of the current +environment, including sections and modules. +\item {\tt Print Section {\ident}.}\comindex{Print Section}\\ +should correspond to a currently open section, this command +displays the objects defined since the beginning of this section. +\item {\tt Print.}\comindex{Print}\\ +This command displays the axioms and variables declarations in the +environment as well as the constants defined since the last variable +was introduced. +\end{Variants} + +\section{Requests to the environment} + +\subsection{\tt Check {\term}.} +\label{Check} +\comindex{Check} +This command displays the type of {\term}. When called in proof mode, +the term is checked in the local context of the current subgoal. + +\begin{Variants} +\item \texttt{Check {\num} {\term}}\\ + Displays the type of {\term} in the context of the {\num}-th + subgoal. +\end{Variants} + +\subsection{\tt Eval {\rm\sl convtactic} in {\term}.} +\comindex{Eval} + +This command performs the specified reduction on {\term}, and displays +the resulting term with its type. The term to be reduced may depend on +hypothesis introduced in the first subgoal (if a proof is in +progress). + +\begin{Variants} +\item \texttt{Eval {\num} {\rm\sl convtactic} in {\term}.}\\ + Evaluates {\term} in the context of the {\num}-th subgoal. +\end{Variants} + +\SeeAlso section~\ref{Conversion-tactics}. + +\subsection{\tt Extraction \ident.} +\label{ExtractionIdent} +\comindex{Extraction} +This command displays the \FW-term extracted from {\ident}. The name +{\ident} must refer to a defined constant or a theorem. The \FW-term +is extracted from the term defining {\ident} when {\ident} is a +defined constant, or from the proof-term when {\ident} is a +theorem. The extraction is processed according to the distinction +between {\Set} and {\Prop}; that is to say, between logical and +computational content (see section \ref{Sorts}). + +\begin{ErrMsgs} +\item \errindex{Non informative term} +\end{ErrMsgs} + +\SeeAlso chapter \ref{Extraction} + +\subsection{\tt Opaque \ident$_1$ \dots \ident$_n$.} +\comindex{Opaque}\label{Opaque} +This command forbids the unfolding of the constants \ident$_1$ \dots +\ident$_n$ by tactics using $\delta$-conversion. Unfolding a constant +is replacing it by its definition. + +By default, {\tt Theorem} and its alternatives are stamped as {\tt + Opaque}. This is to keep with the usual mathematical practice of +{\em 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. + +\SeeAlso sections \ref{Conversion-tactics}, \ref{Automatizing}, +\ref{Theorem} + +\begin{ErrMsgs} +\item \ident\ \errindex{does not exist.}\\ + There is no constant in the environment named + \ident. Nevertheless, if you asked \texttt{Opaque foo bar} + and if \texttt{bar} does not exist, \texttt{foo} is set opaque. +\end{ErrMsgs} + +\subsection{\tt Transparent \ident$_1$ \dots \ident$_n$.} +\comindex{Transparent}\label{Transparent} +This command is the converse of {\tt Opaque}. By default, {\tt + Definition} and {\tt Local} declare objects as {\tt Transparent}. + +\Warning {\tt Transparent} and \texttt{Opaque} are brutal and +not synchronous +with the reset mechanism. If a constant was transparent at point A, if +you set it opaque at point B and reset to point A, you return to state +of point A with the difference that the constant is still opaque. This +can cause changes in tactic scripts behavior. + +%TODO: expliquer le rapport avec les sections + +\begin{ErrMsgs} +\item \errindex{Can not set transparent.}\\ + It is a constant from a required module or a parameter. +\item {\ident} \errindex{does not exist.}\\ + There is no constant in the environment named + \ident. Nevertheless, if you give the command \verb|Transparent foo bar.| + and if \texttt{bar} does not exist, \texttt{foo} is set opaque. +\end{ErrMsgs} + +\SeeAlso sections \ref{Conversion-tactics}, \ref{Automatizing}, +\ref{Theorem} + +\subsection{\tt Search {\ident}.}\comindex{Search} +This command displays the name and type of all theorems of the current +context whose statement's conclusion has the form {\tt ({\ident} t1 .. + tn)}. This command is useful to remind the user of the name of +library lemmas. + +\subsection{\tt SearchIsos {\term}.}\comindex{SearchIsos} +\label{searchisos} +\texttt{SearchIsos} searches terms by their type modulo isomorphism. +This command displays the full name of all constants, variables, +inductive types, and inductive constructors of the current +context whose type is isomorphic to {\term} modulo the contextual part of the +following axiomatization (the mutual inductive types with one constructor, +without implicit arguments, and for which projections exist, are regarded as a +sequence of $\sa{}$): + +\begin{tabbing} +\ \ \ \ \=11.\ \=\kill +\>1.\>$A=B\mx{ if }A\stackrel{\bt{}\io{}}{\lra{}}B$\\ +\>2.\>$\sa{}x:A.B=\sa{}y:A.B[x\la{}y]\mx{ if }y\not\in{}FV(\sa{}x:A.B)$\\ +\>3.\>$\Pi{}x:A.B=\Pi{}y:A.B[x\la{}y]\mx{ if }y\not\in{}FV(\Pi{}x:A.B)$\\ +\>4.\>$\sa{}x:A.B=\sa{}x:B.A\mx{ if }x\not\in{}FV(A,B)$\\ +\>5.\>$\sa{}x:(\sa{}y:A.B).C=\sa{}x:A.\sa{}y:B[y\la{}x].C[x\la{}(x,y)]$\\ +\>6.\>$\Pi{}x:(\sa{}y:A.B).C=\Pi{}x:A.\Pi{}y:B[y\la{}x].C[x\la{}(x,y)]$\\ +\>7.\>$\Pi{}x:A.\sa{}y:B.C=\sa{}y:(\Pi{}x:A.B).(\Pi{}x:A.C[y\la{}(y\sm{}x)]$\\ +\>8.\>$\sa{}x:A.unit=A$\\ +\>9.\>$\sa{}x:unit.A=A[x\la{}tt]$\\ +\>10.\>$\Pi{}x:A.unit=unit$\\ +\>11.\>$\Pi{}x:unit.A=A[x\la{}tt]$ +\end{tabbing} + +For more informations about the exact working of this command, see +\cite{Del97}. + +\section{Loading files} + +\Coq\ offers the possibility of loading different +parts of a whole development stored in separate files. Their contents +will be loaded as if they were entered from the keyboard. This means +that the loaded files are ASCII files containing sequences of commands +for \Coq's toplevel. This kind of file is called a {\em script} for +\Coq\index{Script file}. The standard (and default) extension of +\Coq's script files is {\tt .v}. + +\subsection{\tt Load {\ident}.} +\comindex{Load}\label{Load} +This command loads the file named {\ident}{\tt .v}, searching +successively in each of the directories specified in the {\em + loadpath}. (see section \ref{loadpath}) + +\begin{Variants} +\item {\tt Load {\str}.}\label{Load-str}\\ + Loads the file denoted by the string {\str}, where {\str} is any + complete filename. Then the \verb.~. and {\tt ..} + abbreviations are allowed as well as shell variables. If no + extension is specified, \Coq\ will use the default extension {\tt + .v} +\item {\tt Load Verbose {\ident}.}, + {\tt Load Verbose {\str}}\\ + \comindex{Load Verbose} + Display, while loading, the answers of \Coq\ to each command + (including tactics) contained in the loaded file + \SeeAlso section \ref{Begin-Silent} +\end{Variants} + +\begin{ErrMsgs} +\item \errindex{Can't find file {\ident} on loadpath} +\end{ErrMsgs} + +\section{Compiled files}\label{compiled}\index{Compiled files} + +This feature allows to build files for a quick loading. When loaded, +the commands contained in a compiled file will not be {\em replayed}. +In particular, proofs will not be replayed. This avoids a useless +waste of time. + +\Rem A module containing an open section cannot be compiled. + +\subsection{\tt Compile Module {\ident}.} +\index{Modules} +\comindex{Compile Module} +\index{.vo files} +This command loads the file +{\ident}{\tt .v} and plays the script it contains. Declarations, +definitions and proofs it contains are {\em "packaged"} in a compiled +form: the {\em module} named {\ident}. +A file {\ident}{\tt .vo} is then created. +The file {\ident}{\tt .v} is searched according to the +current loadpath. +The {\ident}{\tt .vo} is then written in the directory where +{\ident}{\tt .v} was found. + +\begin{Variants} +\item \texttt{Compile Module {\ident} {\str}.}\\ + Uses the file {\str}{\tt .v} or {\str} if the previous one does not + exist to build the module {\ident}. In this case, {\str} is any + string giving a filename in the UNIX sense (see section + \ref{Load-str}). + \Warning The given filename can not contain other caracters than + the caracters of \Coq's identifiers : letters or digits or the + underscore symbol ``\_''. + +\item \texttt{Compile Module Specification {\ident}.}\\ + \comindex{Compile Module Specification} + Builds a specification module: only the types of terms are stored + in the module. The bodies (the proofs) are {\em not} written + in the module. In that case, the file created is {\ident}{\tt .vi}. + This is only useful when proof terms take too much place in memory + and are not necessary. + +\item \texttt{Compile Verbose Module {\ident}.}\\ + \comindex{Compile Verbose Module} + Verbose version of Compile: shows the contents of the file being + compiled. +\end{Variants} + +These different variants can be combined. + + +\begin{ErrMsgs} +\item \texttt{You cannot open a module when there are things other than}\\ + \texttt{Modules and Imports in the context.}\\ + The only commands allowed before a {Compile Module} command are {\tt + Require},\\ + {\tt Read Module} and {\tt Import}. Actually, The normal way to + compile modules is by the {\tt coqc} command (see chapter + \ref{Addoc-coqc}). +\end{ErrMsgs} + +\SeeAlso sections \ref{Opaque}, \ref{loadpath}, chapter +\ref{Addoc-coqc} + +\subsection{\tt Read Module {\ident}.}\comindex{Read Module} +Loads the module stored in the file {\ident}, but does not open it: +its contents is invisible to the user. The implementation file +({\ident}{\tt.vo}) is searched first, then the specification file +({\ident}{\tt.vi}) in case of failure. + +\subsection{\tt Require {\ident}.} +\comindex{Require} +\label{Require} +This command loads and opens (imports) the module stored in the file +{\ident}. The implementation file ({\ident}{\tt .vo}) is searched first, +then the specification file ({\ident}{\tt .vi}) in case of failure. +If the module required has already been loaded, \Coq\ +simply opens it (as {\tt Import {\ident}} would do it). +If the module required is already loaded and open, \Coq\ +displays the following warning: {\tt {\ident} already imported}. + +If a module {\it A} contains a command {\tt Require} {\it B} then the +command {\tt Require} {\it A} loads the module {\it B} but does not +open it (See the {\tt Require Export} variant below). + +\begin{Variants} +\item {\tt Require Export {\ident}.}\\ + \comindex{Require Export} + This command acts as {\tt Require} {\ident}. But if a module {\it + A} contains a command {\tt Require Export} {\it B}, then the + command {\tt Require} {\it A} opens the module {\it B} as if the + user would have typed {\tt Require}{\it B}. +\item {\tt Require $[$ Implementation $|$ Specification $]$ {\ident}.}\\ + \comindex{Require Implementation} + \comindex{Require Specification} + Is the same as {\tt Require}, but specifying explicitly the + implementation ({\tt.vo} file) or the specification ({\tt.vi} + file). +\item {\tt Require {\ident} {\str}.}\\ + Specifies the file to load as being {\str}, instead of + {\ident}. The opened module is still {\ident} and therefore + must have been loaded. +\item {\tt Require {\ident} {\str}.}\\ + Specifies the file to load as being {\str}, instead of + {\ident}. The opened module is still {\ident}. +\end{Variants} + +These different variants can be combined. + +\begin{ErrMsgs} +\item \errindex{Can't find module toto on loadpath}\\ + The command did not find the file {\tt toto.vo}. Either {\tt + toto.v} exists but is not compiled or {\tt toto.vo} is in a directory + which is not in your {\tt LoadPath} (see section \ref{loadpath}). +\item \errindex{Bad magic number}\\ + \index{Bad-magic-number@{\tt Bad Magic Number}} + The file {\tt{\ident}.vo} was found but either it is not a \Coq\ + compiled module, or it was compiled with an older and incompatible + version of \Coq. +\end{ErrMsgs} + +\SeeAlso chapter \ref{Addoc-coqc} + +\subsection{\tt Print Modules.} +\comindex{Print Modules} +This command shows the currently loaded and currently opened +(imported) modules. + +\subsection{\tt Declare ML Module {\str$_1$} .. {\str$_n$}.} +\comindex{Declare ML Module} +This commands loads the Objective Caml compiled files {\str$_1$} \dots +{\str$_n$} (dynamic link). It is mainly used to load tactics +dynamically (see chapter \ref{WritingTactics}). The files are +searched into the current Objective Caml loadpath (see the command {\tt +Add ML Path} in the section \ref{loadpath}). Loading of Objective Caml +files is only possible under the bytecode version of {\tt coqtop} +(i.e. not using options {\tt -opt} or {\tt -full} -- see chapter +\ref{Addoc-coqc}). + +\subsection{\tt Print ML Modules.}\comindex{Print ML Modules} +This print the name of all \ocaml modules loaded with \texttt{Declare + ML Module}. To know from where these module were loaded, the user +should use the command \texttt{Locate File} (\pageref{Locate File}) + +\section{Loadpath} +\label{loadpath}\index{Loadpath} + +There are currently two loadpaths in \Coq. A loadpath where seeking +{\Coq} files (extensions {\tt .v} or {\tt .vo} or {\tt .vi}) and one where +seeking Objective Caml files. The default loadpath contains the +directory ``\texttt{.}'' denoting the current directory, so there also +commands to print and change the current working directory. + +\subsection{\tt Pwd.}\comindex{Pwd}\label{Pwd} +This command displays the current working directory. + +\subsection{\tt Cd {\str}.}\comindex{Cd} +This command changes the current directory according to {\str} +which can be any valid path. + +\begin{Variants} +\item {\tt Cd.}\\ + Is equivalent to {\tt Pwd.} +\end{Variants} + +\subsection{\tt AddPath {\str}.}\comindex{AddPath} +This command adds the path {\str} to the current \Coq\ loadpath. + +\subsection{\tt AddRecPath {\str}.}\comindex{AddRecPath} +This command adds the directory {\str} and all its subdirectories +to the current \Coq\ loadpath. + +\subsection{\tt DelPath {\str}.}\comindex{DelPath} +This command removes the path {\str} from the current \Coq\ loadpath. + +\subsection{\tt Print LoadPath.}\comindex{Print LoadPath} +This command displays the current \Coq\ loadpath. + +\subsection{\tt Add ML Path {\str}.}\comindex{Add ML Path} +This command adds the path {\str} to the current Objective Caml loadpath (see +the command {\tt Declare ML Module} in the section \ref{compiled}). + +\subsection{\tt Add Rec ML Path {\str}.}\comindex{Add Rec ML Path} +This command adds the directory {\str} and all its subdirectories +to the current Objective Caml loadpath (see +the command {\tt Declare ML Module} in the section \ref{compiled}). + +\subsection{\tt Print ML Path {\str}.}\comindex{Print ML Path} +This command displays the current Objective Caml loadpath. +This command makes sense only under the bytecode version of {\tt +oqtop}, i.e. not using {\tt -opt} or {\tt -full} options (see the +command {\tt Declare ML Module} in the section +\ref{compiled}). + +\subsection{\tt Locate File {\str}.}\comindex{Locate + File}\label{Locate File} +This command displays the location of file {\str} in the current loadpath. +Typically, {\str} is a \texttt{.cmo} or \texttt{.vo} or \texttt{.v} file. + +\subsection{\tt Locate Library {\ident}.} +\comindex{Locate Library} +This command displays the location of the \Coq\ module {\ident} in the current +loadpath. Is is equivalent to {\tt Locate File "}{\ident}{\tt .vo".} + +\subsection{\tt Locate {\ident}.}\comindex{Locate} +This command displays the full name of the identifier {\ident} +and consequently the \Coq\ module in which it is defined. + +\section{States and Reset} + +\subsection{\tt Reset \ident.} +\comindex{Reset} +This command removes all the objects in the environment since \ident\ +was introduced, including \ident. \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. + +\begin{ErrMsgs} +\item \errindex{cannot reset to a nonexistent object} +\end{ErrMsgs} + +\subsection{\tt Save State \ident.} +\comindex{Save State} +Saves the current state of the development (mainly the defined +objects) such that one can go back at this point if necessary. + +\begin{Variants} +\item {\tt Save State \ident\ \str.} \\ + Associates to the state of name {\tt ident} the string {\str} as a + comment. +\end{Variants} + +\subsection{\tt Print States.} +\comindex{Print States} + +Prints the names of the currently saved states with the associated +comment. The state {\tt Initial} is automatically built by the system +and can not be removed. + +\subsection{\tt Restore State \ident.} +\comindex{Restore State} +Restores the set of known objects in the state {\ident}. + +\begin{Variants} +\item {\tt Reset Initial.}\comindex{Reset Initial}\\ + Is equivalent to {\tt Restore State Initial} and goes back to the + initial state (like after the command {\tt coqtop}). +\end{Variants} + +\subsection{\tt Remove State \ident.} +\comindex{Remove State} +Remove the state \ident\ from the states list. + +\subsection{\tt Write States \str.} +\comindex{Write States} +Writes the current list of states into a UNIX file \str{\tt .coq} for +use in a further session. This file can be given as the {\tt + inputstate} argument of the commands {\tt coqtop} and {\tt coqc}. A +command {\tt Restore State \ident} is necessary afterwards to choose +explicitly which state to use (the default is to use the last saved state). + +\begin{Variants} +\item {\tt Write States \ident} The suffix \texttt{.coq} is implicit, + and the state is saved in the current directory (see \pageref{Pwd}). +\end{Variants} + +\section{Syntax facilities} + +We present quickly in this section some syntactic facilities. +We will only sketch them here and refer the +interested reader to chapter \ref{Addoc-syntax} for more details and +examples. + +\subsection{\tt Implicit Arguments $[$ On $|$ Off $]$.} +\comindex{Implicit Arguments On} +\comindex{Implicit Arguments Off} + +These commands sets and unsets the implicit argument mode. This mode +forces not explicitly give some arguments (typically type arguments in +polymorphic functions) which are deductible from the other arguments. + +\SeeAlso section \ref{Auto-implicit} + +\subsection{\tt Syntactic Definition {\ident} := \term.} +\comindex{Syntactic Definition} +\ttindex{?} +This command defines {\ident} as an +abbreviation with implicit arguments. Implicit arguments are denoted +in {\term} by {\tt ?} and they will have to be synthesized by the +system. + +\Rem Since it may contain don't care variables {\tt ?}, the argument +{\term} cannot be typechecked at +definition time. But each of its subsequent usages will be. + +\SeeAlso section \ref{Syntactic-Definition} + + +\subsection{\tt Syntax {\ident} {\rm\sl syntax-rules}.} +\comindex{Syntax}\index{Pretty printing} +This command addresses the extensible +pretty-printing mechanism of \Coq. It allows {\ident$_2$} to be +pretty-printed as specified in {\rm\sl syntax-rules}. Many examples +of the {\tt Syntax} command usage may be found in the {\tt + PreludeSyntax} file (see directory {\tt \$COQLIB/theories/INIT}). + +\SeeAlso chapter \ref{Addoc-syntax} + +\subsection{\tt Grammar \ident$_1$ \ident$_2$ := {\rm\sl + grammar-rule}.} +\comindex{Grammar}\index{Extensive grammars} +This command allows to give explicitly new grammar rules for parsing +the user's own notation. It may be used instead of the {\tt Syntactic +Definition} pragma. It can also be used by an advanced \Coq's user +who programs his own tactics. + +\SeeAlso chapters \ref{Addoc-syntax}, +\ref{WritingTactics} + +\subsection{\tt{Infix} {\num} {\str} {\ident}.}\comindex{Infix} + +This command declares a prefix operator {\ident} as infix, with the +syntax {\term} {\str} {\term}. {\num} is the precedence associated to +the operator; it must lie between 1 and 10. The infix operator \str\ +associates to the left. {\str} must be a legal token. Both grammar +and pretty-print rules are automatically generated for {\str}. + +\begin{Variants} +\item \texttt{Infix {\rm\sl assoc} {\num} {\str} {\ident}.} \\ + Declares {\ident} as an infix operator with an alternate + associativity. {\rm\sl assoc} may be one of {\tt LEFTA}, {\tt + RIGHTA} and {\tt NONA}. The default is {\tt LEFTA}. When an + associativity is given, the precedence level must lie between 6 and + 9. +\end{Variants} + +% Distfix not documented. + +\section{Miscellaneous} + +\subsection{\tt Quit.}\comindex{Quit} +This command permits to quit \Coq. + +\subsection{\tt Drop.}\comindex{Drop}\label{Drop} + +This is used mostly as a debug facility by \Coq's implementors +and does not concern the casual user. +This command permits to leave {\Coq} temporarily and enter the +Objective Caml toplevel. The Objective Caml command: + +\begin{flushleft} +\begin{verbatim} +#use "include.ml";; +\end{verbatim} +\end{flushleft} + +\noindent add the right loadpaths and loads some toplevel printers for +all abstract types of \Coq - section\_path, identfifiers, terms, judgements, +\dots. You can also use the file \texttt{base\_include.ml} instead, +that loads only the pretty-printers for section\_paths and +identfifiers. See section \ref{test-and-debug} more information on the +usage of the toplevel. You can return back to \Coq{} with the command: + +\begin{flushleft} +\begin{verbatim} +go();; +\end{verbatim} +\end{flushleft} + +\begin{Warnings} +\item It only works if the bytecode version of {\Coq} was +invoked. It does not work if {\Coq} was invoked with the option +{\tt -opt} or {\tt -full} (see \pageref{binary-images}). +\item You must have downloaded the \emph{source code} of \Coq{} (not the + binary distribution), to have compiled \Coq{} and to set the + environment variable \texttt{COQTOP} to the right value (see + \ref{EnvVariables}) +\end{Warnings} + +\subsection{\tt Begin Silent.} +\comindex{Begin Silent} +\label{Begin-Silent} +\index{Silent mode} +This command turns off the normal displaying. + +\subsection{\tt End Silent.}\comindex{End Silent} +This command turns the normal display on. + +\subsection{\tt Time.}\comindex{Time} +\label{time} +This commands turns on the Time Search Display mode. The Time Search Display +mode shows the user and system times for the {\tt SearchIsos} requests. + +\subsection{\tt Untime.}\comindex{Untime} +This commands turns off the Time Search Display mode (see section~\ref{time}). + +%\subsection{\tt Explain ...} +%Not yet documented. + +%\subsection{\tt Go ...} +%Not yet documented. + +%\subsection{\tt Abstraction ...} +%Not yet documented. + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/RefMan-pre.tex b/doc/RefMan-pre.tex new file mode 100755 index 000000000..36346b88c --- /dev/null +++ b/doc/RefMan-pre.tex @@ -0,0 +1,293 @@ +\setheaders{Credits} +\chapter*{Credits} +%\addcontentsline{toc}{section}{Credits} + +{\Coq} is a proof assistant for higher-order logic, allowing the +development of computer programs consistent with their formal +specification. It is the result of about ten years of research of the +Coq project. We shall briefly survey here three main aspects: the +{\sl logical language} in which we write our axiomatizations and +specifications, the {\sl proof assistant} which allows the development +of verified mathematical proofs, and the {\sl program extractor} which +synthesizes computer programs obeying their formal specifications, +written as logical assertions in the language. + +The logical language used by {\Coq} is a variety of type theory, +called the {\sl 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 {\sl types}. This effort +culminated with {\sl Principia Mathematica}, the first systematic +attempt at a formal foundation of mathematics. A simplification of +this system along the lines of simply typed $\lambda$-calculus +occurred with Church's {\sl Simple Theory of Types}. The +$\lambda$-calculus notation, originally used for expressing +functionality, could also be used as an encoding of natural deduction +proofs. This Curry-Howard isomorphism was used by N. de Bruijn in the +{\sl Automath} project, the first full-scale attempt to develop and +mechanically verify mathematical proofs. This effort culminated with +Jutting's verification of Landau's {\sl Grundlagen} in the 1970's. +Exploiting this Curry-Howard isomorphism, notable achievements in +proof theory saw the emergence of two type-theoretic frameworks; the +first one, Martin-L\"of's {\sl Intuitionistic Theory of Types}, +attempts a new foundation of mathematics on constructive principles. +The second one, Girard's polymorphic $\lambda$-calculus $F_\omega$, is +a very strong functional system in which we may represent higher-order +logic proof structures. Combining both systems in a higher-order +extension of the Automath languages, T. Coquand presented in 1985 the +first version of the {\sl 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 {\sl Calculus of Inductive Constructions}. This +extended formalism is not rigorously defined here. Rather, numerous +concrete examples are discussed. We refer the interested reader to +relevant research papers for more information about the formalism, its +meta-theoretic properties, and semantics. However, it should not be +necessary to understand this theoretical material in order to write +specifications. It is possible to understand the Calculus of Inductive +Constructions at a higher level, as a mixture of predicate calculus, +inductive predicate definitions presented as typed PROLOG, and +recursive function definitions close to the language ML. + +Automated theorem-proving was pioneered in the 1960's by Davis and +Putnam in propositional calculus. A complete mechanization (in the +sense of a semi-decision procedure) of classical first-order logic was +proposed in 1965 by J.A. Robinson, with a single uniform inference +rule called {\sl resolution}. Resolution relies on solving equations +in free algebras (i.e. term structures), using the {\sl unification + algorithm}. Many refinements of resolution were studied in the +1970's, but few convincing implementations were realized, except of +course that PROLOG is in some sense issued from this effort. A less +ambitious approach to proof development is computer-aided +proof-checking. The most notable proof-checkers developed in the +1970's were LCF, designed by R. Milner and his colleagues at U. +Edinburgh, specialized in proving properties about denotational +semantics recursion equations, and the Boyer and Moore theorem-prover, +an automation of primitive recursion over inductive data types. While +the Boyer-Moore theorem-prover attempted to synthesize proofs by a +combination of automated methods, LCF constructed its proofs through +the programming of {\sl tactics}, written in a high-level functional +meta-language, ML. + +The salient feature which clearly distinguishes our proof assistant +from say LCF or Boyer and Moore's, is its possibility to extract +programs from the constructive contents of proofs. This computational +interpretation of proof objects, in the tradition of Bishop's +constructive mathematics, is based on a realizability interpretation, +in the sense of Kleene, due to C. Paulin. The user must just mark his +intention by separating in the logical statements the assertions +stating the existence of a computational object from the logical +assertions which specify its properties, but which may be considered +as just comments in the corresponding program. Given this information, +the system automatically extracts a functional term from a consistency +proof of its specifications. This functional term may be in turn +compiled into an actual computer program. This methodology of +extracting programs from proofs is a revolutionary paradigm for +software engineering. Program synthesis has long been a theme of +research in artificial intelligence, pioneered by R. Waldinger. The +Tablog system of Z. Manna and R. Waldinger allows the deductive +synthesis of functional programs from proofs in tableau form of their +specifications, written in a variety of first-order logic. Development +of a systematic {\sl programming logic}, based on extensions of +Martin-L\"of's type theory, was undertaken at Cornell U. by the Nuprl +team, headed by R. Constable. The first actual program extractor, PX, +was designed and implemented around 1985 by S. Hayashi from Kyoto +University. It allows the extraction of a LISP program from a proof +in a logical system inspired by the logical formalisms of S. Feferman. +Interest in this methodology is growing in the theoretical computer +science community. We can foresee the day when actual computer systems +used in applications will contain certified modules, automatically +generated from a consistency proof of their formal specifications. We +are however still far from being able to use this methodology in a +smooth interaction with the standard tools from software engineering, +i.e. compilers, linkers, run-time systems taking advantage of special +hardware, debuggers, and the like. We hope that {\Coq} can be of use +to researchers interested in experimenting with this new methodology. + +A first implementation of CoC was started in 1984 by G. Huet and T. +Coquand. Its implementation language was CAML, a functional +programming language from the ML family designed at INRIA in +Rocquencourt. The core of this system was a proof-checker for CoC seen +as a typed $\lambda$-calculus, called the {\sl Constructive Engine}. +This engine was operated through a high-level notation permitting the +declaration of axioms and parameters, the definition of mathematical +types and objects, and the explicit construction of proof objects +encoded as $\lambda$-terms. A section mechanism, designed and +implemented by G. Dowek, allowed hierarchical developments of +mathematical theories. This high-level language was called the {\sl + Mathematical Vernacular}. Furthermore, an interactive {\sl Theorem + Prover} permitted the incremental construction of proof trees in a +top-down manner, subgoaling recursively and backtracking from +dead-alleys. The theorem prover executed tactics written in CAML, in +the LCF fashion. A basic set of tactics was predefined, which the +user could extend by his own specific tactics. This system (Version +4.10) was released in 1989. Then, the system was extended to deal +with the new calculus with inductive types by C. Paulin, with +corresponding new tactics for proofs by induction. A new standard set +of tactics was streamlined, and the vernacular extended for tactics +execution. A package to compile programs extracted from proofs to +actual computer programs in CAML or some other functional language was +designed and implemented by B. Werner. A new user-interface, relying +on a CAML-X interface by D. de Rauglaudre, was designed and +implemented by A. Felty. It allowed operation of the theorem-prover +through the manipulation of windows, menus, mouse-sensitive buttons, +and other widgets. This system (Version 5.6) was released in 1991. + +Coq was ported to the new implementation Caml-light of X. Leroy and D. +Doligez by D. de Rauglaudre (Version 5.7) in 1992. A new version of +Coq was then coordinated by C. Murthy, with new tools designed by C. +Parent to prove properties of ML programs (this methodology is dual to +program extraction) and a new user-interaction loop. This system +(Version 5.8) was released in May 1993. A Centaur interface CTCoq was +then developed by Y. Bertot from the Croap project from +INRIA-Sophia-Antipolis. + +In parallel, G. Dowek and H. Herbelin developed a new proof engine, +allowing the general manipulation of existential variables +consistently with dependent types in an experimental version of Coq +(V5.9). + +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-oriented way. This new architecture, due to C. Murthy, +supports several new facilities which make the system easier to extend +and to scale up: + +\begin{itemize} +\item User-programmable tactics are allowed +\item It is possible to separately verify development modules, and to + load their compiled images without verifying them again - a quick + relocation process allows their fast loading +\item A generic parsing scheme allows user-definable notations, with a + symmetric table-driven pretty-printer +\item Syntactic definitions allow convenient abbreviations +\item A limited facility of meta-variables allows the automatic + synthesis of certain type expressions, allowing generic notations + for e.g. equality, pairing, and existential quantification. +\end{itemize} + +In the Fall of 1994, C. Paulin-Mohring replaced the structure of +inductively defined types and families by a new structure, allowing +the mutually recursive definitions. P. Manoury implemented a +translation of recursive definitions into the primitive recursive +style imposed by the internal recursion operators, in the style of the +ProPre system. C. Mu{\~n}oz implemented a decision procedure for +intuitionistic propositional logic, based on results of R. Dyckhoff. +J.C. Filli{\^a}tre implemented a decision procedure for first-order +logic without contraction, based on results of J. Ketonen and R. +Weyhrauch. Finally C. Murthy implemented a library of inversion +tactics, relieving the user from tedious definitions of ``inversion +predicates''. + +\begin{flushright} +Rocquencourt, Feb. 1st 1995\\ +Gérard Huet +\end{flushright} + +\section*{Credits: addendum for version 6.1} +%\addcontentsline{toc}{section}{Credits: addendum for version V6.1} + +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. + +The new version provides powerful tools for easier developments. + +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. + +Amokrane Saïbi wrote a mechanism to simulate +inheritance between types families extending a proposal by Peter +Aczel. He also developed a mechanism to automatically compute which +arguments of a constant may be inferred by the system and consequently +do not need to be explicitly written. + +Yann Coscoy designed a command which explains a proof term using +natural language. Pierre Cr{\'e}gut built a new tactic which solves +problems in quantifier-free Presburger Arithmetic. Both +functionalities have been integrated to the Coq system by Hugo +Herbelin. + +Samuel Boutin designed a tactic for simplification of commutative +rings using a canonical set of rewriting rules and equality modulo +associativity and commutativity. + +Finally the organisation of the \Coq\ distribution has been supervised +by Jean-Christophe Filliâtre with the help of Judicaël Courant +and Bruno Barras. + +\begin{flushright} +Lyon, Nov. 18th 1996\\ +Christine Paulin +\end{flushright} +\newpage + +\section*{Credits: addendum for version 6.2} +%\addcontentsline{toc}{section}{Credits: addendum for version V6.2} + +In version 6.2 of Coq, the parsing is done using camlp4, a +preprocessor and pretty-printer for CAML designed by Daniel de +Rauglaudre at INRIA. Daniel de Rauglaudre made the first adaptation +of 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-error messages. The user-interface to introduce grammar or +pretty-printing rules has also changed. + +Eduardo Giménez redesigned the internal +tactic libraries, giving uniform names +to Caml functions corresponding to Coq tactic names. + +Bruno Barras wrote new more efficient reductions functions. + +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-friendly notations for arithmetic +expressions. + +New tactics were introduced: Eduardo Giménez improved a mechanism to +introduce macros for tactics, and designed special tactics for +(co)inductive definitions; Patrick Loiseleur designed a tactic to +simplify polynomial expressions in an arbitrary commutative ring which +generalizes the previous tactic implemented by Samuel Boutin. +Jean-Christophe Filli\^atre introduced a tactic for refining a goal, +using a proof term with holes as a proof scheme. + +David Delahaye designed the \textsf{SearchIsos} tool to search an +object in the library given its type (up to isomorphism). + +Henri Laulhère produced the Coq distribution for the Windows environment. + +Finally, Hugo Herbelin was the main coordinator of the Coq documentation with +principal contributions by Bruno Barras, David Delahaye, +Jean-Christophe Filli\^atre, Eduardo +Giménez, Hugo Herbelin and Patrick Loiseleur. + +\begin{flushright} +Orsay, May 4th 1998\\ +Christine Paulin +\end{flushright} + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: + diff --git a/doc/RefMan-pro.tex b/doc/RefMan-pro.tex new file mode 100755 index 000000000..c9bc4e4d9 --- /dev/null +++ b/doc/RefMan-pro.tex @@ -0,0 +1,291 @@ +\chapter{Proof handling} +\index{Proof editing} +\label{Proof-handling} + +In \Coq's proof editing mode all top-level commands documented in +chapter \ref{Vernacular-commands} remain available +and the user has access to specialized commands dealing with proof +development pragmas documented in this section. He can also use some +other specialized commands called {\em tactics}. They are the very +tools allowing the user to deal with logical reasoning. They are +documented in chapter \ref{Tactics}.\\ +When switching in editing proof mode, the prompt +\index{Prompt} +{\tt Coq <} is changed into {\tt {\ident} <} where {\ident} is the +declared name of the theorem currently edited. + +At each stage of a proof development, one has a list of goals to +prove. Initially, the list consists only in the theorem itself. After +having applied some tactics, the list of goals contains the subgoals +generated by the tactics. + +To each subgoal is associated a number of +hypotheses we call the {\em \index*{local context}} of the goal. +Initially, the local context is empty. It is enriched by the use of +certain tactics (see mainly section \ref{Intro}). + +When a proof is achieved the message {\tt Subtree proved!} is +displayed. One can then store this proof as a defined constant in the +environment. Because there exists a correspondence between proofs and +terms of $\lambda$-calculus, known as the {\em Curry-Howard +isomorphism} \cite{How80,Bar91,Gir89,Hue89}, \Coq~ stores proofs as +terms of {\sc Cic}. Those terms are called {\em proof + terms}\index{Proof term}. + +It is possible to edit several proofs at the same time: see section +\ref{Resume} + +\ErrMsg When one attempts to use a proof editing command out of the +proof editing mode, \Coq~ raises the error message : {\tt No focused + proof}. + +\section{Switching on/off the proof editing mode} + +\subsection{\tt Goal {\form}.} +\comindex{Goal}\label{Goal} +This command switches \Coq~ to editing proof mode and sets {\form} as +the original goal. It associates the name {\tt Unnamed\_thm} to +that goal. + +\begin{ErrMsgs} +\item \errindex{Proof objects can only be abstracted} +\item \errindex{A goal should be a type} +\item \errindex{repeated goal not permitted in refining mode} +\end{ErrMsgs} + +\SeeAlso section \ref{Theorem} + +\subsection{\tt Qed.}\comindex{Qed}\label{Qed} +This command is available in interactive editing proof mode when the +proof is completed. Then {\tt Qed} extracts a proof term from the +proof script, switches back to {\Coq} top-level and attaches the +extracted proof term to the declared name of the original goal. This +name is added to the environment as an {\tt Opaque} constant. + +\begin{ErrMsgs} +\item \errindex{Attempt to save an incomplete proof} +\item \errindex{Clash with previous constant ...}\\ + The implicit name is already defined. You have then to provide + explicitly a new name (see variant 2 below). +\item Sometimes an error occurs when building the proof term, +because tactics do not enforce completely the term construction +constraints. + +The user should also be aware of the fact that since the proof term is +completely rechecked at this point, one may have to wait a while when +the proof is large. In some exceptional cases one may even incur a +memory overflow. +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Save.}\comindex{Save}\ + Is equivalent to {\tt Qed}. +\item {\tt Save {\ident}.}\\ + Forces the name of the original goal to be {\ident}. +\item {\tt Save Theorem {\ident}.} \\ + Is equivalent to {\tt Save {\ident}.} +\item {\tt Save Remark {\ident}.}\\ + Defines the proved term as a local constant that will not exist + anymore after the end of the current section. +\item {\tt Defined.}\comindex{Defined} \label{Defined} \\ + Defines the proved term as a transparent constant. +\end{Variants} + +\subsection{\tt Theorem {\ident} : {\form}.}\comindex{Theorem}\label{Theorem} +This command switches to interactive editing proof mode and declares +{\ident} as being the name of the original goal {\form}. When declared +as a {\tt Theorem}, the name {\ident} is known at all section levels: +{\tt Theorem} is a {\sl global} lemma. + +\ErrMsg (see section \ref{Goal}) + +\begin{Variants} +\item {\tt Lemma {\ident} : {\form}.}\comindex{Lemma}\\ + It is equivalent to {\tt Theorem {\ident} : {\form}.} +\item {\tt Remark {\ident} : {\form}.}\comindex{Remark}\\ + Analogous to {\tt Theorem} except that {\ident} will be unknown + after closing the current section. All proofs of persistent objects + (such as theorems) referring to {\ident} within the section will be + replaced by the proof of {\ident}. +\item {\tt Fact {\ident} : {\form}.}\comindex{Fact}\\ + Analogous to {\tt Theorem} except that {\ident} is known after + closing the current section but + will be unknown after closing the section which is above the current section. +\item {\tt Definition {\ident} : {\form}.} +\comindex{Definition}\\ + Analogous to {\tt Theorem}, intended to be used in conjunction with + {\tt Defined} (see \ref{Defined}) in order to define a + transparent constant. +\end{Variants} + +\subsection{\tt Proof {\term}.}\comindex{Proof} +This command applies in proof editing mode. It is equivalent to {\tt + Exact {\term}; Save.} That is, you have to give the full proof in +one gulp, as a proof term (see section \ref{Exact}). + +\begin{Variants} +\item{\tt Proof.} is a noop which is useful to delimit the sequence of +tactic commands which start a proof, after a {\tt Theorem} command. +It is a good practice to use {\tt Proof.} as an opening parenthesis, +closed in the script with a closing {\tt Qed.} +\end{Variants} + +\subsection{\tt Abort.}\comindex{Abort} +This command cancels the current proof development, switching back to +the previous proof development, or to the \Coq\ toplevel if no other +proof was edited. + +\begin{ErrMsgs} +\item \errindex{No focused proof}\texttt{ (No proof-editing in progress)} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Abort {\ident}.}\\ + Aborts the editing of the proof named {\ident}. +\item {\tt Abort All.}\\ + Aborts all current goals, switching back to the \Coq\ toplevel. +\end{Variants} + +\subsection{\tt Suspend.}\comindex{Suspend} +This command applies in proof editing mode. It switches back to the +\Coq\ toplevel, but without canceling the current proofs. + +\subsection{\tt Resume.} +\comindex{Resume}\label{Resume} +This commands switches back to the editing of the last edited proof. + +\begin{ErrMsgs} +\item \errindex{No proof-editing in progress} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Resume {\ident}.}\\ + Restarts the editing of the proof named {\ident}. This can be used + to navigate between currently edited proofs. +\end{Variants} + +\begin{ErrMsgs} +\item \errindex{No such proof} +\end{ErrMsgs} + +\section{Navigation in the proof tree} + +\subsection{\tt Undo.}\comindex{Undo} +This command cancels the effect of the last tactic command. Thus, it +backtracks one step. + +\begin{ErrMsgs} +\item \errindex{No focused proof (No proof-editing in progress)} +\item \errindex{Undo stack would be exhausted} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Undo {\num}.}\\ + Repeats {\tt Undo} {\num} times. +\end{Variants} + +\subsection{\tt Set Undo {\num}.}\comindex{Set Undo} +This command changes the maximum number of {\tt Undo}'s that will be +possible when doing a proof. It only affects proofs started after +this command, such that if you want to change the current undo limit +inside a proof, you should first restart this proof. + +\subsection{\tt Unset Undo.}\comindex{Unset Undo} +This command resets the default number of possible {\tt Undo} commands +(which is currently 12). + +\subsection{\tt Restart.}\comindex{Restart} +This command restores the proof editing process to the original goal. + +\begin{ErrMsgs} +\item \errindex{No focused proof to restart} +\end{ErrMsgs} + +\subsection{\tt Focus.}\comindex{Focus} +Will focus the attention on the first subgoal to prove, the remaining +subgoals will no more be printed after the application of a tactic. +This is useful when there are many current subgoals which clutter your +screen. + +\subsection{\tt Unfocus.}\comindex{Unfocus} +Turns off the focus mode. + + +\section{Displaying information} + +\subsection{\tt Show.}\comindex{Show}\label{Show} +This command displays the current goals. + +\begin{Variants} +\item {\tt Show {\num}.}\\ + Displays only the {\num}-th subgoal.\\ +\begin{ErrMsgs} +\errindex{No such goal} +\errindex{No focused proof} +\end{ErrMsgs} + +\item {\tt Show Implicits.}\comindex{Show Implicits}\\ + Displays the current goals, printing the implicit arguments of + constants. + +\item {\tt Show Implicits {\num}.}\\ + Same as above, only displaying the {\num}-th subgoal. + +\item {\tt Show Script.}\comindex{Show Script}\\ + Displays the whole list of tactics applied from the beginning + of the current proof. + This tactics script may contain some holes (subgoals not yet proved). + They are printed as \verb!<Your Tactic Text here>!. + +\item {\tt Show Tree.}\comindex{Show Tree}\\ +This command can be seen as a more structured way of +displaying the state of the proof than that +provided by {\tt Show Script}. Instead of just giving +the list of tactics that have been applied, it +shows the derivation tree constructed by then. +Each node of the tree contains the conclusion +of the corresponding sub-derivation (i.e. a +goal with its corresponding local context) and +the tactic that has generated all the +sub-derivations. The leaves of this tree are +the goals which still remain to be proved. + +%\item {\tt Show Node}\comindex{Show Node}\\ +% Not yet documented + +\item {\tt Show Proof.}\comindex{Show Proof}\\ +It displays the proof term generated by the +tactics that have been applied. +If the proof is not completed, this term contain holes, +which correspond to the sub-terms which are still to be +constructed. These holes appear as a question mark indexed +by an integer, and applied to the list of variables in +the context, since it may depend on them. +The types obtained by abstracting away the context from the +type of each hole-placer are also printed. + +\item {\tt Show Conjectures.}\comindex{Show Conjectures}\\ +It prints the list of the names of all the theorems that +are currently being proved. +As it is possible to start proving a previous lemma during +the proof of a theorem, this list may contain several +names. +\end{Variants} + +\subsection{\tt Set Hyps\_limit {\num}.} +\comindex{Set Hyps\_limit} +This command sets the maximum number of hypotheses displayed in +goals after the application of a tactic. +All the hypotheses remains usable in the proof development. + +\subsection{\tt Unset Hyps\_limit.} +\comindex{Unset Hyps\_limit} +This command goes back to the default mode which is to print all +available hypotheses. + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/RefMan-syn.tex b/doc/RefMan-syn.tex new file mode 100755 index 000000000..9b79c5c57 --- /dev/null +++ b/doc/RefMan-syn.tex @@ -0,0 +1,1716 @@ +\chapter{Syntax extensions} +\label{Addoc-syntax} + +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. As in +most compilers, there is an intermediate structure called {\em Abstract +Syntax Tree} (AST). Parsing a term is done in two steps\footnote{ + We omit the lexing step, which simply translates a character stream + into a token stream. If this translation fails, this is a + \emph{Lexical error}. +}: +\begin{enumerate} +\item An AST is build from the input (a stream of tokens), following + grammar rules. This step consists in deciding whether the input + belongs to the language or not. If it is, the parser transforms the + expression into an AST. If not, this is a syntax error. An expression + belongs to the language if there exists a sequence of grammar rules + that recognizes it. This task is delegated to {\camlpppp}. See the + Reference Manual~\cite{ddr98} for details on the parsing + technology. The transformation to AST is performed by executing + successively the {\sl actions} bound to these rules. + +\item The AST is translated into the internal representation of + commands and terms. At this point, we detect unbound variables and + determine the exact section-path of every global value. Then, the term + may be typed, computed,~\ldots +\end{enumerate} +The printing process is the reverse: commands or terms are first +translated into AST's, and then the pretty-printer translates this AST +into a printing orders stream, according to printing rules. + +In {\Coq}, only the translations between AST's and the concrete +representation are extendable. One can modify the set of grammar and +printing rules, but one cannot change the way AST's are interpreted in +the internal level. + +In the following section, we describe the syntax of AST expressions, +involved in both parsing and printing. The next two sections deal with +extendable grammars and pretty-printers. + +\section{Abstract syntax trees (AST)} +\index{AST} +\index{Abstract syntax tree} + +\label{astsyntax} + +The AST expressions are conceptually divided into two classes: +\emph{constructive expressions} (those that can be used in parsing +rules) and \emph{destructive expressions} (those that can be used in +pretty printing rules). In the following we give the concrete syntax +of expressions and some examples of their usage. + +The BNF grammar {\sl ast} in Fig.~\ref{astexpr} defines the syntax +of both constructive and destructive expressions. The lexical +conventions are the same as in section~\ref{lexical}. Let us first +describe the features common to constructive and destructive +expressions. + +\begin{figure} +\begin{center} +\begin{tabular}{|rclr|} +\hline +{\sl ast} & ::= & {\sl meta} & (metavariable) \\ +& $|$ & {\ident} & (variable)\\ +& $|$ & {\integer} & (positive integer)\\ +& $|$ & {\sl string} & (quoted string) \\ +& $|$ & {\sl path} & (section-path) \\ +& $|$ & \verb+{+ {\ident} \verb+}+ & (identifier) \\ +& $|$ & \verb+[+ {\sl name} \verb+]+ {\sl ast} & (abstraction) \\ +& $|$ & \verb+(+ {\ident}~~\sequence{{\sl ast}}{} \verb+)+ + & (application node)\\ +& $|$ & \verb+(+ {\sl special-tok}~~{\sl meta} \verb+)+ + & (special-operator) \\ +& $|$ & \verb+'+ {\sl ast} & (quoted ast) \\ +& $|$ & {\sl quotation} & \\ + +{\sl meta} & ::= & \verb+$+{\ident} & \\ +{\sl path} & ::= & \nelist{{\tt\#}{\ident}}{} \verb+.+ {\sl kind} & \\ +{\sl kind} & ::= & \verb+cci+ $~|~$\verb+fw+ $~|~$ \verb+obj+ & \\ +{\sl name} & ::= & \verb+<>+ ~$|$~ {\ident} ~$\mid$~ {\sl meta} & \\ + +{\sl special-tok} & ::= & + \verb+$LIST+~$|$~\verb+$VAR+~$|$~\verb+$NUM+~$|$~% + \verb+$STR+~$|$~\verb+$PATH+~$|$~\verb+$ID+ & \\ + +{\sl quotation}& ::= & + \verb+<<+ ~{\sl meta-command}~ \verb+>>+ & \\ +& $|$ & \verb+<:command:<+ ~{\sl meta-command}~ \verb+>>+ & \\ +& $|$ & \verb+<:vernac:<+ ~{\sl meta-vernac}~ \verb+>>+ & \\ +& $|$ & \verb+<:tactic:<+ ~{\sl meta-tactic}~ \verb+>>+ & \\ +\hline +\end{tabular} +\end{center} +\caption{Syntax of AST expressions}\label{astexpr} +\end{figure} + +\subsubsection{Atomic AST} + +An atomic AST can be either a variable, a natural number, a quoted +string, a section path or an identifier. They are the basic components +of an AST. + +\subsubsection{Metavariable} +\index{Metavariable} + +As we will see later, metavariables may denote an AST or an AST list. +So, we introduce two types of variables: \verb+Ast+ and +\verb+List+. The type of variables is checked statically: an +expression referring to undefined metavariables, or using metavariables +with an inappropriate type, will be rejected. + +Metavariables are used to perform substitutions in constructive +expressions: they are replaced by their value in a given +environment. They are also involved in the pattern matching operation: +metavariables in destructive patterns create new bindings in the +environment. + +\subsubsection{Application node} + +Note that the AST syntax is rather general, since application nodes +may be labelled by an arbitrary identifier (but not a metavariable), +and operators have no fixed arity. This enables the extensibility of +the system. + +Nevertheless there are some application nodes that have some special +meaning for the system. They are build on \verb+(+{\sl +special-tok}~{\sl meta}\verb+)+, and cannot be confused with regular +nodes since {\sl special-tok} begins with a \verb+$+. There is a +description of these nodes below. + +\subsubsection{Abstraction} + +The equality on AST's is the $\alpha$-conversion, i.e. two AST's are +equal if only they are the same up to renaming of bound variables +(thus, \verb+[x]x+ is equal to \verb+[y]y+). This makes the difference +between variables and identifiers clear: the former may be bound by +abstractions, whereas identifiers cannot be bound. To illustrate this, +\verb+[x]{x}+ is equal to \verb+[y]{x}+, but not to \verb+[y]{y}+. + +The binding structure of AST is used to represent the binders in the +terms of {\Coq}: the product \verb+(x:$A)$B+ is mapped to the AST +\verb+(PROD $A [x]$B)+, whereas the non dependent product +\verb+$A->$B+ is mapped to \verb+(PROD $A [<>]$B)+ (\verb+[<>]t+ is an +anonymous abstraction). + +Metavariables can appear in abstractions. In that case, the value of +the metavariable must be a variable (or a list of variables). If not, +a run-time error is raised. + +\subsubsection{Quoted AST} +\index{Quoted AST} + +The \verb+'+$t$ construction means that the AST $t$ should not be +interpreted at all. The main effect is that metavariables occurring in +it cannot be substituted or considered as binding in patterns. + +\subsubsection{Quotations} +\index{Quotations} + +The non terminal symbols {\sl meta-command}, {\sl meta-vernac} and +{\sl meta-tactic} stand, respectively, for the syntax of commands, +vernacular phrases and tactics. The prefix {\sl meta-} is just to +emphasize that the expression may refer to metavariables. + +Indeed, if the AST to generate corresponds to a term that already has +a syntax, one can call a grammar to parse it and to return the AST +result. For instance, \verb+<<(eq ? $f $g)>>+ denotes the AST which is +the application (in the sense of CIC) of the constant {\tt eq} to +three arguments. It is coded as an AST node labelled {\tt APPLIST} +with four arguments. + +This term is parsable by \verb+command command+ grammar. This grammar +is invoked on this term to generate an AST by putting the term between +``\verb+<<+'' and ``\verb+>>+''. + +We can also invoke the initial grammars of several other predefined +entries (see section~\ref{predefined-grammars} for a description of +these grammars). + +\begin{itemize} +\item \verb|<< t >>| parses {\tt t} with {\tt command command} grammar +(terms of CIC). +\item \verb|<:command:< t >>| parses {\tt t} with {\tt command command} + grammar (same as \verb|<< t >>|). +\item \verb|<:vernac:< t >>| parses {\tt t} with {\tt vernac vernac} + grammar (vernacular commands). +\item \verb|<:tactic:< t >>| parses {\tt t} with {\tt tactic tactic} + grammar (tactic expressions). +\end{itemize} + +\Warning +One cannot invoke other grammars than those described. + +\subsubsection{Special operators in constructive expressions} + +The expressions \verb+($LIST $x)+ injects the AST list variable +{\tt\$x} in an AST position. For example, an application node is +composed of an identifier followed by a list of AST's that are glued +together. Each of these expressions must denote an AST. If we want to +insert an AST list, one has to use the \verb+$LIST+ operator. Assume +the variable \verb+$idl+ is bound to the list \verb+[x y z]+, the +expression \verb+(Intros ($LIST $idl) a b c)+ will build the AST +\verb+(Intros x y z a b c)+. Note that \verb+$LIST+ does not occur in +the result. + +% Ameliorer le style! +Since we know the type of variables, the \verb+$LIST+ is not really +necessary. We enforce this annotation to stress on the fact that the +variable will be substituted by an arbitrary number of AST's. + +The other special operators ({\tt\$VAR}, {\tt\$NUM}, {\tt\$STR}, +{\tt\$PATH} and {\tt\$ID}) are forbidden. + +\subsubsection{Special operators in destructive expressions (AST patterns)} +\label{patternsyntax} +\index{AST patterns} + +% pas encore implante (serait utile pour afficher les LAMBDALIST et +% PRODLIST). +%\item \verb+($SLAM $l body)+ is used to denote an abstraction where +% the elements of the list variable \verb+$l+ are the variables +% simultaneously abstracted in \verb+body+. +% The production to recognize a lambda abstraction of the form +% $[x_1,\ldots,x_n:T]body$ use the operator \verb+$SLAM+: + +A pattern is an AST expression, in which some metavariables can +appear. In a given environment a pattern matches any AST which is +equal (w.r.t $\alpha$-conversion) to the value of the pattern in an +extension of the current environment. The result of the matching is +precisely this extended environment. This definition allows +non-linear patterns (i.e. patterns in which a variable occurs several +times). + +For instance, the pattern \verb+(PAIR $x $x)+ matches any AST which is +a node labelled {\tt PAIR} applied to two identical arguments, and +binds this argument to {\tt\$x}. If {\tt\$x} was already bound, the +arguments must also be equal to the current value of {\tt\$x}. + +The ``wildcard pattern'' \verb+$_+ is not a regular metavariable: it +matches any term, but does not bind any variable. The pattern +\verb+(PAIR $_ $_)+ matches any {\tt PAIR} node applied to two +arguments. + +The {\tt\$LIST} operator still introduces list variables. Typically, +when a metavariable appears as argument of an application, one has to +say if it must match \emph{one} argument (binding an AST variable), or +\emph{all} the arguments (binding a list variable). Let us consider +the patterns \verb+(Intros $id)+ and \verb+(Intros ($LIST $idl))+. The +former matches nodes with \emph{exactly} one argument, which is bound +in the AST variable {\tt\$id}. On the other hand, the latter pattern +matches any AST node labelled {\tt Intros}, and it binds the +\emph{list} of its arguments to the list variable {\tt\$idl}. The +{\tt\$LIST} pattern must be the last item of a list pattern, because +it would make the pattern matching operation more complicated. The +pattern \verb+(Intros ($LIST $idl) $lastid)+ is not accepted. + +The other special operators allows checking what kind of leaf we +are destructing: +\begin{itemize} +\item{\tt\$VAR} matches only variables +\item{\tt\$NUM} matches natural numbers +\item{\tt\$STR} matches quoted strings +\item{\tt\$PATH} matches section-paths +\item{\tt\$ID} matches identifiers +\end{itemize} +\noindent For instance, the pattern \verb+(DO ($NUM $n) $tc)+ matches +\verb+(DO 5 (Intro))+, and creates the bindings ({\tt\$n},5) and +({\tt\$tc},\verb+(Intro)+). The pattern matching would fail on +\verb+(DO "5" (Intro))+. + +\section{Extendable grammars} +\label{Grammar} +\index{Extendable Grammars} +\comindex{Grammar} + +Grammar rules can be added with the {\tt Grammar} command. This +command is just an interface towards {\camlpppp}, providing the +semantic actions so that they build the expected AST. A simple grammar +command has the following syntax: \index{Grammar@{\tt Grammar}} + +\begin{center} +\texttt{Grammar}~\textsl{entry}~\textsl{nonterminal}~\texttt{:=}~% +\textsl{rule-name}~\textsl{LMP}~\verb+->+~\textsl{action}~\texttt{.} +\end{center} + +The components have the following meaning: +\begin{itemize} +\item a grammar name: defined by a parser entry and a non-terminal. + Non-terminals are packed in an \emph{entry} (also called + universe). One can have two non-terminals of the same name if they + are in different entries. A non-terminal can have the same name as + its entry. +\item a rule (sometimes called production), formed by a name, a left + member of production and an action, which generalizes constructive + expressions. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{figure} +\begin{center} +\begin{tabular}{|rcl|} +\hline +{\sl grammar} & ::= & + \verb+Grammar+~{\sl entry}~\nelist{{\sl gram-entry}}{with} \\ +{\sl entry}& ::= & {\ident} \\ +{\sl gram-entry} & ::= & + {\sl rule-name}~\zeroone{{\tt :}~{\sl entry-type}}~\verb+:=+~% +% [{\sl assoc}]~ +\sequence{{\sl production}}{|} \\ +{\sl rule-name} & ::= & {\ident} \\ +{\sl entry-type} & ::= & \verb+Ast+~$|$~\verb+List+ \\ +%{\sl assoc} & ::= & \verb+LEFTA+~$|$~\verb+RIGHTA+~$|$~\verb+NONA+ \\ +% parler de l'associativite ? +% Cela n'a pas vraiment de sens si toutes les re`gles sont dans un +% meme +% niveau. +{\sl production} & ::= & + {\sl rule-name}~\verb+[+~\sequence{{\sl prod-item}}{}~\verb+] ->+ + ~{\sl action}\\ +{\sl rule-name} & ::= & {\sl ident} \\ +{\sl prod-item} & ::= & {\sl string} \\ +& | & \zeroone{{\sl entry}~{\tt :}}~{\sl entry-name}~% + \zeroone{{\tt (}~{\sl meta}~{\tt )}} \\ +{\sl action} & ::= & + \verb+[+~\sequence{{\sl ast}}{}~\verb+]+ \\ +& | & \verb+let+~{\sl pattern}~\verb+=+~{\sl action}~% + \verb+in+~{\sl action} \\ +& | & {\tt case}~{\sl action}~\zeroone{{\tt :}~{\sl entry-type}}~{\tt of}~% + \sequence{{\sl case}}{|}~{\tt esac} \\ +{\sl case} & ::= & \sequence{{\sl pattern}}{}~\verb+->+~{\sl action} \\ +{\sl pattern} & ::= & {\sl ast} \\ +\hline +\end{tabular} +\end{center} +\caption{Syntax of the grammar extension command}\label{grammarsyntax} +\end{figure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +The exact syntax of the {\tt Grammar} command is defined +in Fig.~\ref{grammarsyntax}. +It is possible to extend a grammar with several rules at once. +$$ +\begin{array}{rcc} +\verb+Grammar+~~entry~~nonterminal + & \verb+:=+ & production_1 \\ + & \verb+|+ & \vdots \\ + & \verb+|+ & production_n \verb+.+ \\ +\end{array} +$$ +Productions are entered in reverse order (i.e. $production_n$ before +$production_1$), so that the first rules have priority over the last +ones. The set of rules can be read as an usual pattern matching. + +\noindent Also, we can extend several grammars of a given universe at +the same time. The order of non-terminals does not matter since they +extend different grammars. +$$ +\begin{array}{rcccc} +\verb+Grammar+ & entry & nonterminal_1 + & \verb+:=+ & production_1^1 \\ + && & \verb+|+ & \vdots \\ + && & \verb+|+ & production_{n_1}^1 \\ + & \verb+with+ & \vdots && \\ + & \verb+with+ & nonterminal_p + & \verb+:=+ & production_1^p \\ + && & \verb+|+ & \vdots \\ + && & \verb+|+ & production_{n_p}^p \verb+.+ \\ +\end{array} +$$ + + +\subsection{Grammar entries} +\index{Grammar entries} +\label{predefined-grammars} + +Let us describe the four predefined entries. Each of them (except {\tt +prim}) possesses an initial grammar for starting the parsing process. + +\begin{itemize} +\item \verb+prim+ : it is the entry of the primitive grammars. Most of + them cannot be defined by the extendable grammar mechanism. They are + encoded inside the system. The entry contains the following + non-terminals: + +\begin{itemize} +\item \verb+var+ : variable grammar. Parses an identifier and builds +an AST which is a variable. +\item \verb+ident+ : identifier grammar. Parses an identifier and +builds an AST which is an identifier such as \verb+{x}+. +\item \verb+number+ : number grammar. Parses a positive integer. +\item \verb+string+ : string grammar. Parses a quoted string. +\item \verb+path+ : section path grammar. +\item \verb+ast+ : AST grammar. +\item \verb+astpat+ : AST pattern grammar. +\item \verb+astact+ : action grammar. +\end{itemize} + +The primitive grammars are used as the other grammars; for instance +the variables of terms are parsed by \verb+prim:var($id)+. + +\item \verb+command+ : it is the term entry. It allows to have a + pretty syntax for terms. Its initial grammar is {\tt command + command}. This entry contains several non-terminals, among them {\tt + command0} to {\tt command10} which stratify the terms according to + priority levels (\verb+0+ to \verb+10+). These priority levels allow + us also to specify the order of associativity of operators. + +% Ce serait bien si on etait capables de donner une table avec les +% niveaux de priorite de chaque operateur... + +\item \verb+vernac+ : it is the vernacular command entry, with {\tt + vernac vernac} as initial grammar. Thanks to it, the developers can + define the syntax of new commands they add to the system. As to + users, they can change the syntax of the predefined vernacular + commands. + +\item \verb+tactic+ : it is the tactic entry with {\tt tactics tactic} + as initial grammar. This entry allows to define the syntax of new + tactics. See chapter~\ref{WritingTactics} about user-defined tactics + for more details. + +\end{itemize} + +The user can define new entries and new non-terminals, using the +grammar extension command. A grammar does not have to be explicitly +defined. But the grammars in the left member of rules must all be +defined, possibly by the current grammar command. It may be convenient +to define an empty grammar, just so that it may be called by other +grammars, and extend this empty grammar later. Assume that the {\tt +command command13} does not exist. The next command defines it with +zero productions. + +\begin{coq_example*} +Grammar command command13 := . +\end{coq_example*} + +The grammars of new entries do not have an initial grammar. To use +them, they must be called (directly or indirectly) by grammars of +predefined entries. We give an example of a (direct) call of the +grammar {\tt newentry nonterm} by {\tt command command}. This +following rule allows to use the syntax \verb+a&b+ for the conjunction +\verb+a/\b+. + +\begin{coq_example} +Grammar newentry nonterm := + ampersand [ "&" command:command($c) ] -> [$c]. +Grammar command command := + new_and [ command8($a) newentry:nonterm($b) ] -> [<<$a/\$b>>]. +\end{coq_example} + + +\subsection{Left member of productions (LMP)} + +A LMP is composed of a combination of terminals (enclosed between +double quotes) and grammar calls specifying the entry. It is enclosed +between ``\verb+[+'' and ``\verb+]+''. The empty LMP, represented by +\verb+[ ]+, corresponds to $\epsilon$ in formal language theory. + +A grammar call is done by \verb+entry:nonterminal($id)+ where: +\begin{itemize} +\item \verb+entry+ and \verb+nonterminal+ + specifies the entry of the grammar, and the non-terminal. +\item \verb+$id+ is a metavariable that will receive the AST or AST + list resulting from the call to the grammar. +\end{itemize} + +The elements \verb+entry+ and \verb+$id+ are optional. The grammar +entry can be omitted if it is the same as the entry of the +non-terminal we are extending. Also, \verb+$id+ is omitted if we do +not want to get back the AST result. Thus a grammar call can be +reduced to a non-terminal. + +Each terminal must contain exactly one token. This token does not need +to be already defined. If not, it will be automatically +added. Nevertheless, any string cannot be a token (e.g. blanks should +not appear in tokens since parsing would then depend on +indentation). We introduce the notion of \emph{valid token}, as a +sequence, without blanks, of characters taken from the following list: +\begin{center} +\verb"< > / \ - + = ; , | ! @ # % ^ & * ( ) ? : ~ $ _ ` ' a..z A..Z 0..9" +\end{center} +that do not start with a character from +\begin{center} +\verb!$ _ a..z A..Z ' 0..9! +\end{center} + +When an LMP is used in the parsing process of an expression, it is +analyzed from left to right. Every token met in the LMP should +correspond to the current token of the expression. As for the grammars +calls, they are performed in order to recognize parts of the initial +expression. + +\Warning +Unlike destructive expressions, if a variable appears several times in +the LMP, the last binding hides the previous ones. Comparison can be +performed only in the actions. + + +\firstexample +\example{Defining a syntax for inequality} + +The rule below allows us to use the syntax \verb+t1#t2+ for the term +\verb+~t1=t2+. + +\begin{coq_example} +Grammar command command1 := + not_eq [ command0($a) "#" command0($b) ] -> [<<~($a=$b)>>]. +\end{coq_example} + +The level $1$ of the grammar of terms is extended with one rule named +\texttt{not\_eq}. When this rule is selected, its LMP calls the +grammar \verb+command+ \verb+command0+. This grammar recognizes a term +that it binds to the metavariable \verb+$a+. Then it meets the token +``\verb+#+'' and finally it calls the grammar \verb+command+ +\verb+command0+. This grammar returns the recognized term in +\verb+$b+. The action constructs the term \verb+~($a=$b)+. Note that +we use the command quotation on the right-hand side. + +\Warning +Metavariables are identifiers preceded by the ``\verb+$+'' symbol. +They cannot be replaced by identifiers. For instance, if we enter a +rule with identifiers and not metavariables, an error occurs: + +\begin{coq_example} +Grammar command command1 := + not_eq [ command0(a) "#" command0(b) ] -> [<<~(a=b)>>]. +\end{coq_example} + +For instance, let us give the statement of the symmetry of \verb+#+: + +\begin{coq_example} +Goal (A:Set)(a,b:A) a#b -> b#a. +\end{coq_example} + +\begin{coq_eval} +Abort. +\end{coq_eval} + +Conversely, one can force \verb+~a=b+ to be printed \verb=a#b= by +giving pretty-printing rules. This is explained in section \ref{Syntax}. + +\example{Redefining vernac commands} + +Thanks to the following rule, ``{\tt |- term.}'' will have the same +effect as ``{\tt Goal term.}''. + +\begin{coq_eval} +Save State no_thesis. +\end{coq_eval} + +\begin{coq_example} +Grammar vernac vernac := + thesis [ "|" "-" command:command($term) "." ] + -> [<:vernac:<Goal $term.>>]. +\end{coq_example} + +\noindent This rule allows putting blanks between the bar and the +dash, as in + +\begin{coq_example} +| - (A:Prop)A->A. +\end{coq_example} + +\begin{coq_eval} +Restore State no_thesis. +\end{coq_eval} + +\noindent Assuming the previous rule has not been entered, we can +forbid blanks with a rule that declares ``\verb+|-+'' as a single +token: + +\begin{coq_example} +Grammar vernac vernac := + thesis [ "|-" command:command($term) "." ] + -> [<:vernac:<Goal $term.>>]. +| - (A:Prop)A->A. +\end{coq_example} + +\noindent If both rules were entered, we would have three tokens +\verb+|+, \verb+-+ and \verb+|-+. The lexical ambiguity on the string +\verb+|-+ is solved according to the longest match rule (see lexical +conventions page~\pageref{lexical}), i.e. \verb+|-+ would be one single +token. To enforce the use of the first rule, a blank must be inserted +between the bar and the dash. + + +\Rem +The vernac commands should always be terminated by a period. When a +syntax error is detected, the top-level discards its input until it +reaches a period token, and then resumes parsing. + +\example{Redefining tactics} + +We can give names to repetitive tactic sequences. Thus in this example +``{\tt IntSp}'' will correspond to the tactic {\tt Intros} followed by +{\tt Split}. + +\begin{coq_example} +Grammar tactic simple_tactic := + intros_split [ "IntSp" ] -> [<:tactic:<Intros; Split>>]. +\end{coq_example} + +Let us check that this works. + +\begin{coq_example} +Goal (A,B:Prop)A/\B -> B/\A. +IntSp. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +Note that the same result can be obtained in a simpler way with {\tt +Tactic Definition} (see page~\pageref{TacticDefinition}). However, +this macro can only define tactics which arguments are terms. + + +\example{Priority, left and right associativity of operators} + +The disjunction has a higher priority than conjunction. Thus +\verb+A/\B\/C+ will be parsed as \verb+(A/\B)\/C+ and not as +\verb+A/\(B\/C)+. The priority is done by putting the rule for the +disjunction in a higher level than that of conjunction: conjunction is +defined in the non-terminal {\tt command6} and disjunction in {\tt +command7} (see file {\tt Logic.v} in the library). Notice that +the character ``\verb+\+'' must be doubled (see lexical conventions +for quoted strings on page~\pageref{lexical}). + +\begin{coq_example*} +Grammar command command6 := + and [ command5($c1) "/\\" command6($c2) ] -> [<<(and $c1 $c2)>>]. +Grammar command command7 := + or [ command6($c1) "\\/" command7($c2) ] -> [<<(or $c1 $c2)>>]. +\end{coq_example*} + +Thus conjunction and disjunction associate to the right since in both +cases the priority of the right term (resp. {\tt command6} and {\tt +command7}) is higher than the priority of the left term (resp. {\tt +command5} and {\tt command6}). The left member of a conjunction cannot +be itself a conjunction, unless you enclose it inside parenthesis. + +The left associativity is done by calling recursively the +non-terminal. {\camlpppp} deals with this recursion by first trying +the non-left-recursive rules. Here is an example taken from the +standard library, defining a syntax for the addition on integers: + +\begin{coq_example*} +Grammar znatural expr := + expr_plus [ expr($p) "+" expr($c) ] -> [<<(Zplus $p $c)>>]. +\end{coq_example*} + + + +\subsection{Actions} +\label{GramAction} +\index{Grammar Actions} + +Every rule should generate an AST corresponding to the syntactic +construction that it recognizes. This generation is done by an +action. Thus every rule is associated to an action. The syntax has +been defined in Fig.~\ref{grammarsyntax}. We give some examples. + +\subsubsection{Simple actions} + +A simple action is an AST enclosed between ``\verb+[+'' and +``\verb+]+''. It simply builds the AST by interpreting it as a +constructive expression in the environment defined by the LMP. This +case has been illustrated in all the previous examples. We will later +see that grammars can also return AST lists. + + +\subsubsection{Local definitions} + +When an action should generate a big term, we can use +\texttt{let}~\textsl{pattern}~\texttt{=}~\textsl{action}$_1$~% +\texttt{in}~\textsl{action}$_2$\index{let@{\tt let}} expressions to +construct it progressively. The action \textsl{action}$_1$ is first +computed, then it is matched against \textsl{pattern} which may bind +metavariables, and the result is the evaluation of \textsl{action}$_2$ +in this new context. + +\example{} + +\noindent From the syntax \verb|t1*+t2|, we generate the term +{\tt (plus (plus t1 t2) (mult t1 t2))}. + +\begin{coq_example} +Grammar command command1 := + mult_plus [ command0($a) "*" "+" command0($b) ] + -> let $p1=[<<(plus $a $b)>>] in + let $p2=[<<(mult $a $b)>>] in + [<<(plus $p1 $p2)>>]. +\end{coq_example} + +Let us give an example with this syntax: + +\begin{coq_example} +Goal (O*+O)=O. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\subsubsection{Conditional actions} + +We recall the syntax of conditional actions: + +\begin{center} +\texttt{case}~\textsl{action}~\texttt{of}~% +\textsl{pattern}$_1$~\verb+->+~\textsl{action}$_1$~% +\texttt{|}~$\cdots$~\texttt{|}~% +\textsl{pattern}$_n$~\verb+->+~\textsl{action}$_n$~% +\texttt{esac} +\end{center}\index{case@@{\tt case}} + +The action to execute is chosen according to the value of +\textsl{action}. The matching is performed from left to right. The +selected action is the one associated to the first pattern that +matches the value of \textsl{action}. This matching operation will +bind the metavariables appearing in the selected pattern. The pattern +matching does need being exhaustive, and no warning is emitted. When the +pattern matching fails a message reports in which grammar rule the +failure happened. + +\example{Overloading the ``$+$'' operator} + +The internal representation of an expression such as {\tt A+B} depends +on the shape of {\tt A} and {\tt B}: +\begin{itemize} +\item \verb/{P}+{Q}/ uses {\tt sumbool} +\item otherwise,\verb/A+{Q}/ uses {\tt sumor} +\item otherwise, \verb/A+B/ uses {\tt sum}. +\end{itemize} +The trick is to build a temporary AST: \verb/{A}/ generates the node +\verb/(SQUASH A)/. When we parse \verb/A+B/, we remove the {\tt +SQUASH} in {\tt A} and {\tt B}: + +\begin{coq_example*} +Grammar command command1 := + squash [ "{" lcommand($lc) "}" ] -> [(SQUASH $lc)]. +Grammar command lassoc_command4 := + squash_sum + [ lassoc_command4($c1) "+" lassoc_command4($c2) ] -> + case [$c2] of + (SQUASH $T2) -> + case [$c1] of + (SQUASH $T1) -> [<<(sumbool $T1 $T2)>>] + | $_ -> [<<(sumor $c1 $T2)>>] + esac + | $_ -> [<<(sum $c1 $c2)>>] + esac. +\end{coq_example*} + +\noindent The problem is that sometimes, the intermediate {\tt SQUASH} +node cannot re-shaped, then we have a very specific error: + +\begin{coq_example} +Check {True}. +\end{coq_example} + + +\example{Comparisons and non-linear patterns} + +The patterns may be non-linear: when an already bound metavariable +appears in a pattern, the value yielded by the pattern matching must +be equal, up to renaming of bound variables, to the current +value. Note that this does not apply to the wildcard \verb+$_+. For +example, we can compare two arguments: + +\begin{coq_example} +Grammar command command10 := + refl_equals [ command9($c1) "||" command9($c2) ] -> + case [$c1] of $c2 -> [<<(refl_equal ? $c2)>>] esac. +Check ([x:nat]x || [y:nat]y). +\end{coq_example} + +\noindent The metavariable \verb+$c1+ is bound to \verb+[x:nat]x+ and +\verb+$c2+ to \verb+[y:nat]y+. Since these two values are equal, the +pattern matching succeeds. It fails when the two terms are not equal: + +\begin{coq_example} +Check ([x:nat]x || [z:bool]z). +\end{coq_example} + + + +\subsection{Grammars of type {\tt List}} + +Assume we want to define an non-terminal {\tt ne\_identarg\_list} that +parses an non-empty list of identifiers. If the grammars could only +return AST's, we would have to define it this way: + +\begin{coq_example*} +Grammar tactic my_ne_ident_list := + ident_list_cons [ identarg($id) my_ne_ident_list($l) ] -> + case [$l] of + (IDENTS ($LIST $idl)) -> [(IDENTS $id ($LIST $idl))] + esac +| ident_list_single [ identarg($id) ] -> [(IDENTS $id)]. +\end{coq_example*} + +But it would be inefficient: every time an identifier is read, we +remove the ``boxing'' operator {\tt IDENTS}, and put it back once the +identifier is inserted in the list. + +To avoid these awkward trick, we allow grammars to return AST +lists. Hence grammars have a type ({\tt Ast} or {\tt List}), just like +AST's do. Type-checking can be done statically. + +The simple actions can produce lists by putting a list of constructive +expressions one beside the other. As usual, the {\tt\$LIST} operator +allows to inject AST list variables. + +\begin{coq_example*} +Grammar tactic ne_identarg_list : List := + ne_idl_cons [ identarg($id) ne_identarg_list($idl) ] + -> [ $id ($LIST $idl) ] +| ne_idl_single [ identarg($id) ] -> [ $id ]. +\end{coq_example*} + +Note that the grammar type must be recalled in every extension +command, or else the system could not discriminate between a single +AST and an AST list with only one item. If omitted, the default type +is {\tt Ast}. The following command fails because {\tt +ne\_identarg\_list} is already defined with type {\tt List} but the +{\tt Grammar} command header assumes its type is {\tt Ast}. + +\begin{coq_example} +Grammar tactic ne_identarg_list := + list_two [ identarg($id1) identarg($id2) ] -> [ $id1 $id2 ]. +\end{coq_example} + +All rules of a same grammar must have the same type. For instance, the +following rule is refused because the \verb+command command1+ grammar +has been already defined with type {\tt Ast}, and cannot be extended +with a rule returning AST lists. + +\begin{coq_example} +Grammar command command1 := + carret_list [ command0($c1) "^" command0($c2)] -> [ $c1 $c2 ]. +\end{coq_example} + + +\subsection{Limitations} + +The extendable grammar mechanism have four serious limitations. The +first two are inherited from {\camlpppp}. +\begin{itemize} +\item Grammar rules are factorized syntactically: {\camlpppp} does not + try to expand non-terminals to detect further factorizations. The + user must perform the factorization himself. +\item The grammar is not checked to be \emph{LL(1)}\index{LL(1)} when + adding a rule. If it is not LL(1), the parsing may fail on an input + recognized by the grammar, because selecting the appropriate rule + may require looking several tokens ahead. {\camlpppp} always selects + the most recent rule (and all those that factorize with it) + accepting the current token. +\item There is no command to remove a grammar rule. However there is a + trick to do it. It is sufficient to execute the ``{\tt Reset}'' + command on a constant defined before the rule we want to remove. + Thus we retrieve the state before the definition of the constant, + then without the grammar rule. This trick does not apply to grammar + extensions done in {\ocaml}. +\item Grammar rules defined inside a section are automatically removed + after the end of this section: they are available only inside it. +\end{itemize} + +The command {\tt Print Grammar} prints the rules of a grammar. It is +displayed by {\camlpppp}. So, the actions are not printed, and the +recursive calls are printed \verb+SELF+\index{SELF@{\tt SELF}}. It is +sometimes useful if the user wants to understand why parsing fails, or +why a factorization was not done as expected.\index{Print Grammar@{\tt +Print Grammar}} + +\begin{coq_example} +Print Grammar command command8. +\end{coq_example} + +\subsubsection{Getting round the lack of factorization} +The first limitation may require a non-trivial work, and may lead to +ugly grammars, hardly extendable. Sometimes, we can use a trick to +avoid these troubles. The problem arises in the {\gallina} syntax, to +make {\camlpppp} factorize the rules for application and product. The +natural grammar would be: + +\begin{coq_example} +Grammar command command0 := + parenthesis [ "(" command10($c) ")" ] -> [$c] +| product [ "(" prim:var($id) ":" command($c1) ")" command0($c2) ] -> + [(PROD $c1 [$id]$c2)] +with command10 := + application [ command91($c1) ne_command91_list($lc) ] -> + [(APPLIST $c1 ($LIST $lc))] +| inject_com91 [ command91($c) ] -> [$c]. +Check (x:nat)nat. +\end{coq_example} + +But the factorization does not work, thus the product rule is never +selected since identifiers match the {\tt command10} grammar. The +trick is to parse the ident as a {\tt command10} and check \emph{a +posteriori} that the command is indeed an identifier: + +\begin{coq_example} +Grammar command command0 := + product [ "(" command10($c) ":" command($c1) ")" command0($c2) ] -> + [(PROD $c1 [$c]$c2)]. +Check (x:nat)nat. +\end{coq_example} + +\noindent We could have checked it explicitly with a {\tt case} in +the right-hand side of the rule, but the error message in the +following example would not be as relevant: + +\begin{coq_example} +Check (S O:nat)nat. +\end{coq_example} + +\noindent This trick is not similar to the {\tt SQUASH} node in which +we could not detect the error while parsing. Here, the error pops out +when trying to build an abstraction of {\tt\$c2} over the value of +{\tt\$c}. Since it is not bound to a variable, the right-hand side of +the product grammar rule fails. + +\section{Writing your own pretty printing rules} +\label{Syntax} +\comindex{Syntax} + +There is a mechanism for extending the +vernacular's printer by adding, in the interactive +toplevel, new printing rules. The printing rules are stored into a +table and will be recovered at the moment of the printing by the +vernacular's printer. + +The user can print new constants, tactics and vernacular phrases +with his desired syntax. The printing rules +for new constants should be written {\em after} the definition of the +constants. The rules should be +outside a section if the user wants them to be exported. + +The printing rules corresponding to the heart of the system (primitive +tactics, commands and the vernacular language) are defined, +respectively, in the files {\tt PPTactic.v} and {\tt PPCommand.v} +(in the directory {\tt src/syntax}). These files are automatically +loaded in the initial state. The user is not expected to modify these +files unless he dislikes the way primitive things are printed, in +which case he will have to compile the system after doing the +modifications. + +When the system fails to find a suitable printing rule, a tag +\verb+#GENTERM+\index{GENTERM@{\tt\#GENTERM}} appears in the message. + +In the following we give some examples showing how to write the +printing rules for the non-terminal and terminal symbols of a +grammar. We will test them frequently by inspecting the error +messages. Then, we give the grammar of printing rules and a +description of its semantics. + + +\subsection{The Printing Rules} +\subsubsection{The printing of non terminals} + +The printing is the inverse process of parsing. While a grammar rule +maps an input stream of characters +into an AST, a printing +rule maps an AST into an output stream of printing orders. +So given a certain grammar rule, the printing rule +is generally obtained by inverting the grammar rule. + +Like grammar rules, it is possible to define several rules at the same +time. The exact syntax for complex rules is described +in~\ref{syntaxsyntax}. A simple printing rule is of the form: + +\begin{center} +\verb+Syntax+ ~{\sl universe} +~\verb+level+ ~{\sl precedence}~\verb+:+~{\sl name} +~\verb+[+~{\sl pattern}~\verb+] -> [+~{\sl printing-orders}~\verb+].+ +\end{center} + +where : +\begin{itemize} +\item {\it universe} is an identifier denoting the universe of the AST to + be printed. There is a correspondence between the universe of the + grammar rule used to generate the AST and the one of the printing + rule: + +\begin{center} +\begin{tabular}{|c|c|}\hline +{\em Univ. Grammar} & {\em Univ. Printing} \\ \hline +tactic & tactic \\ \hline +command & constr \\ \hline +\end{tabular} +\end{center} + + The vernac universe has no equivalent in pretty-printing since + vernac phrases are never printed by the system. Error messages are + reported by re-displaying what the user entered. + +\item {\it precedence} is positive integer indicating the precedence + of the rule. In general the precedence for tactics is 0. The + universe of commands is implicitly stratified by the hierarchy of + the parsing rules. We have non terminals \textit{command0}, + \textit{command1}, \ldots, \textit{command10}. + The idea is that objects parsed with the non terminal + $command_i$ have precedence $i$. In most of the cases we fix the + precedence of the printing rules for commands to be the same number + of the non terminal with which it is parsed. + + A precedence may also be a triple of integers. The triples are + ordered in lexicographic order, and the level $n$ is equal to {\tt + [$n~0~0$]}. + +\item {\it name} is the name of the + printing rule. A rule is identified by both its universe and name, + if there are two rules with both the same name and universe, then + the last one overrides the former. + +\item {\it pattern} is a pattern that matches the AST to be + printed. The syntax of patterns is very similar to the grammar for ASTs. + A description of their syntax is given in section + \ref{patternsyntax}. + +\item {\it printing-orders} is the sequence of orders indicating the + concrete layout of the printer. +\end{itemize} + +\firstexample + +\example{Syntax for user-defined tactics.} + +The first usage of the \texttt{Syntax} command might be the printing +order for a user-defined tactic: + +\begin{coq_example*} +Declare ML Module "eqdecide". +Syntax tactic level 0: + ComparePP [(Compare $com1 $com2)] -> + ["Compare" [1 2] $com1 [1 2] $com2]. +\end{coq_example*} + +% meme pas vrai +If such a printing rule is not given, a disgraceful \verb+#GENTERM+ +will appear when typing \texttt{Show Script} or \texttt{Save}. For +a tactic macro defined by a \texttt{Tactic Definition} command, a +printing rule is automatically generated so the user don't have to +write one. + +\example{Defining the syntax for new constants.} + +Let's define the constant \verb+Xor+ in Coq: + +\begin{coq_example*} +Definition Xor := [A,B:Prop] A/\~B \/ ~A/\B. +\end{coq_example*} + +Given this definition, we want to use the syntax of \verb+A X B+ +to denote \verb+(Xor A B)+. To do that we give the grammar rule: + +\begin{coq_example} +Grammar command command7 := + Xor [ command6($c1) "X" command7($c2) ] -> [<<(Xor $c1 $c2)>>]. +\end{coq_example} + +Note that the operator is associative to the right. +Now \verb+True X False+ is well parsed: + +\begin{coq_example} +Goal True X False. +\end{coq_example} + +To have it well printed we extend the printer: + +\begin{coq_example} +Syntax constr level 7: + Pxor [<<(Xor $t1 $t2)>>] -> [ $t1:L " X " $t2:E ]. +\end{coq_example} + +and now we have the desired syntax: + +\begin{coq_example} +Show. +\end{coq_example} + +Let's comment the rule: +\begin{itemize} +\item \verb+constr+ is the universe of the printing rule. + +\item \verb+7+ is the rule's precedence and it is the same one than the + parsing production (command7). + +\item \verb+Pxor+ is the name of the printing rule. + +\item \verb+<<(Xor $t1 $t2)>>+ is the pattern of the AST to be + printed. Between \verb+<< >>+ we are allowed to use the syntax of + command instead of syntax of ASTs. + Metavariables may occur in the pattern but preceded by + \verb+$+. + +\item \verb+$t1:L " X " $t2:E+ are the printing + orders, it tells to print the value of \verb+$t1+ then the symbol + \verb+X+ and then the value of \verb+$t2+. + + The \verb+L+ in the little box \verb+$t1:L+ indicates not + to put parentheses around the value of \verb+$t1+ if its precedence + is {\bf less} than the rule's one. An \verb+E+ instead of the + \verb+L+ would mean not to put parentheses around the value of + \verb+$t1+ if its the precedence is {\bf less or equal} than the + rule's one. + + The associativity of the operator can be expressed in the following + way: + + \verb&$t1:L " X " $t2:E& associates the operator to the right. + + \verb&$t1:E " X " $t2:L& associates to the left. + + \verb&$t1:L " X " $t2:L& is non-associative. + +\end{itemize} + +Note that while grammar rules are related by the name of non-terminals +(such as {\tt command6} and {\tt command7}) printing rules are +isolated. The {\tt Pxor} rule tells how to print an {\tt Xor} +expression but not how to print its subterms. The printer looks up +recursively the rules for the values of \verb+$t1+ and \verb+$t2+. The +selection of the printing rules is strictly determined by the +structure of the AST to be printed. + +This could have been defined with the {\tt Infix} command. + + +\example{Forcing to parenthesize a new syntactic construction} + +You can force to parenthesize a new syntactic construction by fixing +the precedence of its printing rule to a number greater than 9. For +example a possible printing rule for the {\tt Xor} connector in the prefix +notation would be: + +\begin{coq_example*} +Syntax constr level 10: + ex_imp [<<(Xor $t1 $t2)>>] -> [ "X " $t1:L " " $t2:L ]. +\end{coq_example*} + +No explicit parentheses are contained in the rule, nevertheless, when +using the connector, the parentheses are automatically written: + +\begin{coq_example} +Show. +\end{coq_example} + +A precedence higher than 9 ensures that the AST value will be +parenthesized by default in either the empty context or if it occurs +in a context where the instructions are of the form +\verb+$t:L+ or \verb+$t:E+. + + +\example{Dealing with list patterns in the syntax rules} + +The following productions extend the parser to recognize a +tactic called \verb+MyIntros+ that receives a list of identifiers as +argument as the primitive \verb+Intros+ tactic does: + +\begin{coq_example*} +Grammar tactic simple_tactic := + my_intros [ "MyIntros" ne_identarg_list($idl) ] -> + [(MyIntrosWith ($LIST $idl))]. +\end{coq_example*} + +To define the printing rule for \verb+MyIntros+ it is necessary to +define the printing rule for the non terminal \verb+ne_identarg_list+. +In grammar productions the dependency between the non terminals is +explicit. This is not the case for printing rules, where the +dependency between the rules is determined by the structure of the +pattern. So, the way to make explicit the relation between printing +rules is by adding structure to the patterns. + +\begin{coq_example} +Syntax tactic level 0: + myintroswith [(MyIntrosWith ($LIST $L))] -> + [ "MyIntros " (NEIDENTARGLIST ($LIST $L)) ]. +\end{coq_example} + +This rule says to print the string \verb+MyIntros+ and then to print +the value of \\ +\verb+(NEIDENTARGLIST ($LIST $L))+. + +\begin{coq_example} +Syntax tactic level 0: + ne_identarg_list_cons [(NEIDENTARGLIST $id ($LIST $l))] + -> [ $id " " (NEIDENTARGLIST ($LIST $l)) ] +| ne_identarg_list_single [(NEIDENTARGLIST $id)] -> [ $id ]. +\end{coq_example} + + +The first rule says how to print a non-empty list, while the second +one says how to print the list with exactly one element. Note that the +pattern structure of the binding in the first rule ensures its use in +a recursive way. + +Like the order of grammar productions, the order of printing rules +\emph{does matter}. In case of two rules whose patterns superpose +each other the {\bf last} rule is always chosen. In the example, if +the last two rules were written in the inverse order the printing will +not work, because only the rule {\sl ne\_identarg\_list\_cons} would +be recursively retrieved and there is no rule for the empty list. +Other possibilities would have been to write a rule for the empty list +instead of the {\sl ne\_identarg\_list\_single} rule, + +\begin{coq_example} +Syntax tactic level 0: + ne_identarg_list_nil [(NEIDENTARGLIST)] -> [ ]. +\end{coq_example} + +This rule indicates to do nothing in case of the empty list. In this +case there is no superposition between patterns (no critical pairs) +and the order is not relevant. But a useless space would be printed +after the last identifier. + +\example{Defining constants with arbitrary number of arguments} + +Sometimes the constants we define may have an arbitrary number of +arguments, the typical case are polymorphic functions. Let's consider +for example the functional composition operator. The following rule +extends the parser: + +\begin{coq_example*} +Definition explicit_comp := [A,B,C:Set][f:A->B][g:B->C][a:A](g (f a)). +Grammar command command6 := + expl_comp [command5($c1) "o" command6($c2) ] -> + [<<(explicit_comp ? ? ? $c1 $c2)>>]. +\end{coq_example*} + +Our first idea is to write the printing rule just by ``inverting'' the +production: + +\begin{coq_example} +Syntax constr level 6: + expl_comp [<<(explicit_comp ? ? ? $f $g)>>] -> [ $f:L "o" $g:L ]. +\end{coq_example} + +This rule is not correct: \verb+?+ is an ordinary AST (indeed, it is +the AST \verb|(XTRA "ISEVAR")|), and does not behave as the +``wildcard'' pattern \verb|$_|. Here is a correct version of this +rule: + +\begin{coq_example*} +Syntax constr level 6: + expl_comp [<<(explicit_comp $_ $_ $_ $f $g)>>] -> [ $f:L "o" $g:L ]. +\end{coq_example*} + +Let's test the printing rule: + +\begin{coq_example} +Definition Id := [A:Set][x:A]x. +Check (Id nat) o (Id nat). +Check ((Id nat)o(Id nat) O). +\end{coq_example} + +In the first case the rule was used, while in the second one the +system failed to match the pattern of the rule with the AST of +\verb+((Id nat)o(Id nat) O)+. +Internally the AST of this term is the same as the AST of the +term \verb+(explicit_comp nat nat nat (Id nat) (Id nat) O)+. +When the system retrieves our rule it tries to match an application of +six arguments with an application of five arguments (the AST of +\verb+(explicit_comp $_ $_ $_ $f $g)+). Then, the matching fails and +the term is printed using the rule for application. + +Note that the idea of adding a new rule for \verb+explicit_comp+ for +the case of six arguments does not solve the problem, because of the +polymorphism, we can always build a term with one argument more. The +rules for application deal with the problem of having an arbitrary +number of arguments by using list patterns. Let's see these rules: + +\begin{coq_example*} +Syntax constr level 10: + app [(APPLIST $H ($LIST $T))] -> + [ [<hov 0> $H:E (APPTAIL ($LIST $T)):E ] ] + +| apptailcons [(APPTAIL $H ($LIST $T))] -> + [ [1 1] $H:L (APPTAIL ($LIST $T)):E ] +| apptailnil [(APPTAIL)] -> [ ]. +\end{coq_example*} + +The first rule prints the operator of the application, and the second +prints the list of its arguments. Then, one solution to our problem is +to specialize the first rule of the application to the cases where the +operator is \verb+explicit_comp+ and the list pattern has {\bf at +least} five arguments: + +\begin{coq_example*} +Syntax constr level 10: + expl_comp + [(APPLIST <<explicit_comp>> $_ $_ $_ $f $g ($LIST $l))] + -> [ [<hov 0> $f:L "o" $g:L (APPTAIL ($LIST $l)) ] ]. +\end{coq_example*} + +Now we can see that this rule works for any application of the +operator: + +\begin{coq_example} +Check ((Id nat) o (Id nat) O). +Check ((Id nat->nat) o (Id nat->nat) [x:nat]x O). +\end{coq_example} + +In the examples presented by now, the rules have no information about +how to deal with indentation, break points and spaces, the printer +will write everything in the same line without spaces. To indicate the +concrete layout of the patterns, there's a simple language of printing +instructions that will be described in the following section. + + +\subsubsection{The printing of terminals} +The user is not expected to write the printing rules for terminals, +this is done automatically. Primitive printing is done for +identifiers, strings, paths, numbers. For example : + +\begin{coq_example*} +Grammar vernac vernac := + mycd [ "MyCd" prim:string($dir) "." ] -> [(MYCD $dir)]. +Syntax vernac level 0: + mycd [(MYCD $dir)] -> [ "MyCd " $dir ]. +\end{coq_example*} + +There is no more need to encapsulate the \verb+$dir+ meta-variable +with the \verb+$PRIM+ or the \verb+$STR+ operator as in the version +6.1. However, the pattern \verb+(MYCD ($STR $dir))+ would be safer, +because the rule would not be selected to print an ill-formed AST. The +name of default primitive printer is the {\ocaml} function {\tt +print\_token}. If the user wants a particular terminal to be printed +by another printer, he may specify it in the right part of the +rule. Example: + +% Pas encore possible! $num est un id, pas un entier. +%Syntax tactic level 0 : +% do_pp [<<Do $num $tactic>>] +% -> [ "Do " $num:"my_printer" [1 1] $tactic ]. +\begin{coq_example*} +Syntax tactic level 0 : + do_pp [(DO ($NUM $num) $tactic)] + -> [ "Do " $num:"my_printer" [1 1] $tactic ]. +\end{coq_example*} + +The printer \textit{my\_printer} must have been installed as shown +below. + +\subsubsection{Primitive printers} + +Writing and installing primitive pretty-printers requires to have the +sources of the system like writing tactics. + +A primitive pretty-printer is an \ocaml\ function of type +\begin{verbatim} + Esyntax.std_printer -> CoqAst.t -> Pp.std_ppcmds +\end{verbatim} +The first +argument is the global printer, it can be called for example by the +specific printer to print subterms. The second argument is the AST to +print, and the result is a stream of printing orders like : + +\begin{itemize} +\item \verb+'sTR"+\textit{string}\verb+"+ to print the string + \textit{string} +\item \verb+'bRK +\textit{num1 num2} that has the same semantics than + \verb+[+ \textit{num1 num2} \verb+]+ in the print rules. +\item \verb+'sPC+ to leave a blank space +\item \verb+'iNT+ $n$ to print the integer $n$ +\item \ldots +\end{itemize} + +There is also commands to make boxes (\verb+h+ or \verb+hv+, described +in file {\tt src/lib/util/pp.mli}). Once the printer is written, it +must be registered by the command : +\begin{verbatim} + Esyntax.Ppprim.add ("name",my_printer);; +\end{verbatim} +\noindent +Then, in the toplevel, after having loaded the right {\ocaml} module, +it can be used in the right hand side of printing orders using the +syntax \verb+$truc:"name"+. + +The real name and the registered name of a pretty-printer does not +need to be the same. However, it can be nice and simple to give the +same name. + +\subsection{Syntax for pretty printing rules} +\label{syntaxsyntax} + +This section describes the syntax for printing rules. The +metalanguage conventions are the same as those specified for the +definition of the {\sl pattern}'s syntax in section \ref{patternsyntax}. +The grammar of printing rules is the following: + +\begin{center} +\begin{tabular}{|rcl|} \hline +{\sl printing-rule} & ::= & + \verb+Syntax+~{\ident}~~\nelist{{\sl level}}{;} \\ +{\sl level} & ::= & \verb+level+~{\sl precedence}~\verb+:+ + ~\nelist{{\sl rule}}{|} \\ +{\sl precedence} & ::= & + {\integer} ~$|$~ \verb+[+~\integer~\integer~\integer~\verb+]+ \\ +{\sl rule} & ::= & + {\sl ident}~\verb+[+~{\sl pattern}~\verb+] -> [+% + ~\sequence{{\sl printing-order}}{}~\verb+]+ \\ +{\sl printing-order} & ::= & \verb+FNL+ \\ + &$|$& {\sl string} \\ + &$|$& \verb+[+~\integer~\integer~\verb+]+ \\ + &$|$& \verb+[+~box~\sequence{{\sl printing-order}}{}~\verb+]+ \\ + &$|$& {\sl ast}~\zeroone{{\tt :}~{\sl prim-printer}}~% + \zeroone{{\tt :}~{\sl paren-rel}}\\ +{\sl box} & ::= & \verb+<+~{\sl box-type}~\integer~\verb+>+\\ +{\sl box-type} & ::= & ~\verb+hov+~$|$~\verb+hv+~$|$~\verb+v+~$|$~\verb+h+\\ +{\sl paren-rel} & ::= & \verb+L+~$|$~\verb+E+ \\ +{\sl prim-printer} & ::= & {\sl string} \\ +{\sl pattern} & ::= & {\sl ast} \\ +\hline +\end{tabular} +\end{center} + +As already stated, the order of rules in a given level is relevant +(the last ones override the previous ones). + + +\subsubsection{Pretty grammar structures} +The basic structure is the printing order sequence. Each order has a +printing effect and they are sequentially executed. The orders can +be: +\begin{itemize} +\item printing orders +\item printing boxes +\end{itemize} + +\paragraph{Printing orders} +Printing orders can be of the form: +\begin{itemize} +\item \verb+"+{\sl string}\verb+"+ prints the {\sl string}. +\item \verb+FNL+ force a new line. + +\item \texttt{\$t:}\textsl{paren-rel} or + \texttt{\$t:}\textsl{prim-printer}\texttt{:}\textsl{paren-rel} + + {\sl ast} is used to build an AST in current context. The printer + looks up the adequate printing rule and applies recursively this + method. The optional field {\it prim-printer} is a string with the + name primitive pretty-printer to call (The name is not the name of + the {\ocaml} function, but the name given to {\tt + Esyntax.Ppprim.add}). Recursion of the printing is determined by + the pattern's structure. {\it paren-rel} is the following: + +\begin{tabular}{cl} + +\verb+L+ & + if $t$ 's precedence is {\bf less} than the rule's one, then no + parentheses \\ + & around $t$ are written. \\ +\verb+E+ & + if $t$ 's precedence is {\bf less or equal} than the rule's one + then no parentheses \\ + & around $t$ are written. \\ +{\it none} & {\bf never} write parentheses around $t$. +\\\\ +\end{tabular} +\end{itemize} + +\paragraph{Printing boxes} +The concept of formatting boxes is used to describe the concrete +layout of patterns: a box may contain many objects which are orders or +sub\-boxes sequences separated by break\-points; the box wraps around +them an imaginary rectangle. +\begin{enumerate} +\item {\bf Box types} + + The type of boxes specifies the way the components of the box will + be displayed and may be: +\begin{itemize} +\item \verb+h+ : to catenate objects horizontally. +\item \verb+v+ : to catenate objects vertically. +\item \verb+hv+ : to catenate objects as with an ``h box'' but an + automatic vertical folding is applied when the horizontal + composition does not fit into the width of the associated output + device. + +\item \verb+hov+ : to catenate objects horizontally but if the + horizontal composition does not fit, a vertical composition will be + applied, trying to catenate horizontally as many objects as possible. +\end{itemize} + +The type of the box can be followed by a {\it n} offset value, which +is the offset added to the current indentation when breaking lines +inside the box. + + +\item {\bf Boxes syntax} + + A box is described by a sequence surrounded by \verb+[ ]+. The first + element of the sequence is the box type: this type surrounded by the + symbols \verb+< >+ is one of the words \verb+hov+, \verb+hv+, + \verb+v+, \verb+v+ followed by an offset. The default offset is 0 + and the default box type is \verb+h+. + +\item {\bf Break\-points} + + In order to specify where the pretty-printer is allowed to break, + one of the following break-points may be used: + +\begin{itemize} +\item \verb+[0 0]+ is a simple break-point, if the line is not broken + here, no space is included (``Cut''). +\item \verb+[1 0]+ if the line is not broken then a space is printed + (``Spc''). +\item \verb+[i j]+ if the line is broken, the value $j$ is added to the + current indentation for the following line; otherwise $i$ blank spaces + are inserted (``Brk''). +\end{itemize} + +\noindent {\bf Examples :} +It is interesting to test printing rules on ``small'' and ``large'' +expressions in order to see how the break of lines and indentation are +managed. Let's define two constants and make a \verb+Print+ of them to +test the rules. Here are some examples of rules for our constant +\verb+Xor+: + +\begin{coq_example*} +Definition A := True X True. +Definition B := True X True X True X True X True X True X True + X True X True X True X True X True X True. +\end{coq_example*} +\begin{coq_example*} +Syntax constr level 6: + Pxor [<<(Xor $t1 $t2)>>] -> [ $t1:L " X " $t2:E ]. +\end{coq_example*} + + +This rule prints everything in the same line exceeding the line's +width. + +% Avec coq-tex, le bord de l'e'cran n'est pas mate'rialise'. +%\begin{coq_example} +%Print B. +%\end{coq_example} + +\begin{small} +\begin{flushleft} +\verb!Coq < Print B.!\\ +\texttt{\textit{B~=~}}\\ +\texttt{\textit{True~X~True~X~True~X~True~X~True~X~True~X~True~X~True~X~True~X~True~X~Tru}}\\ +\texttt{\textit{e~X~True~X~True}}\\ +\texttt{\textit{~~~~~:~Prop}}\\ +\end{flushleft} +\end{small} + +Let's add some break-points in order to force the printer to break the +line before the operator: + +\begin{coq_example*} +Syntax constr level 6: + Pxor [<<(Xor $t1 $t2)>>] -> [ $t1:L [0 1] " X " $t2:E ]. +\end{coq_example*} + +\begin{coq_example} +Print B. +\end{coq_example} + +The line was correctly broken but there is no indentation at all. To +deal with indentation we use a printing box: + +\begin{coq_example*} +Syntax constr level 6: + Pxor [<<(Xor $t1 $t2)>>] -> + [ [<hov 0> $t1:L [0 1] " X " $t2:E ] ]. +\end{coq_example*} + +With this rule the printing of A is correct, an the printing of B is +indented. + +\begin{coq_example} +Print B. +\end{coq_example} + +If we had chosen the mode \verb+v+ instead of \verb+hov+ : + +\begin{coq_example*} +Syntax constr level 6: + Pxor [<<(Xor $t1 $t2)>>] -> [ [<v 0> $t1:L [0 1] " X " $t2:E ] ]. +\end{coq_example*} + +We would have obtained a vertical presentation: + +\begin{coq_example} +Print A. +\end{coq_example} + +The difference between the presentation obtained with the \verb+hv+ +and \verb+hov+ type box is not evident at first glance. Just for +clarification purposes let's compare the result of this silly rule +using an \verb+hv+ and a \verb+hov+ box type: + +\begin{coq_example*} +Syntax constr level 6: + Pxor [<<(Xor $t1 $t2)>>] -> + [ [<hv 0> "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + [0 0] "----------------------------------------" + [0 0] "ZZZZZZZZZZZZZZZZ" ] ]. +\end{coq_example*} +\begin{coq_example} +Print A. +\end{coq_example} +\begin{coq_example*} +Syntax constr level 6: + Pxor [<<(Xor $t1 $t2)>>] -> + [ [<hov 0> "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + [0 0] "----------------------------------------" + [0 0] "ZZZZZZZZZZZZZZZZ" ] ]. +\end{coq_example*} +\begin{coq_example} +Print A. +\end{coq_example} + +In the first case, as the three strings to be printed do not fit in +the line's width, a vertical presentation is applied. In the second +case, a vertical presentation is applied, but as the last two strings +fit in the line's width, they are printed in the same line. + + +\end{enumerate} + +\subsection{Debugging the printing rules} + + By now, there is almost no semantic check of printing rules in the + system. To find out where the problem is, there are two + possibilities: to analyze the rules looking for the most common + errors or to work in the toplevel tracing the ml code of the + printer. +When the system can't find the proper rule to print an Ast, it prints +\verb+#GENTERM+ \textit{ast}. If you added no printing rule, + it's probably a bug and you can send it to the \Coq\ team. + +\subsubsection{Most common errors} +Here are some considerations that may help to get rid of simple +errors: + +\begin{itemize} +\item make sure that the rule you want to use is not defined in + previously closed section. +\item make sure that {\bf all} non-terminals of your grammar have + their corresponding printing rules. + +\item make sure that the set of printing rules for a certain non + terminal covers all the space of AST values for that non terminal. + +\item the order of the rules is important. If there are two rules + whose patterns superpose (they have common instances) then it is + always the most recent rule that will be retrieved. +\item if there are two rules with the same name and universe the last + one overrides the first one. The system always warns you about + redefinition of rules. +\end{itemize} + +\subsubsection{Tracing the {\ocaml} code of the printer} +Some of the conditions presented above are not easy to verify when +dealing with many rules. In that case tracing the code helps to +understand what is happening. The printers are in the file {\tt +src/typing/printer}. There you will find the functions: + +\begin{itemize} +\item {\tt gencompr} : the printer of commands +\item {\tt gentacpr} : the printer of tactics +\end{itemize} + +These printers are defined in terms of a general printer {\tt +genprint} (this function is located in {\tt src/parsing/esyntax.ml}) +and by instantiating it with the adequate parameters. {\tt genprint} +waits for: the universe to which this AST belongs ({\it tactic}, {\it +constr}), a default printer, the precedence of the AST inherited from +the caller rule and the AST to print. {\tt genprint} looks for a rule +whose pattern matches the AST, and executes in order the printing +orders associated to this rule. Subterms are printed by recursively +calling the generic printer. If no rule matches the AST, the default +printer is used. + +An AST of a universe may have subterms that belong to another +universe. For instance, let $v$ be the AST of the tactic +expression \verb+MyTactic O+. The function {\tt gentacpr} is called +to print $v$. This function instantiates the general printer {\tt +genprint} with the universe {\it tactic}. Note that $v$ has a subterm +$c$ corresponding to the AST of \verb+O+ ($c$ belongs to the universe +{\it constr}). {\tt genprint} will try recursively to print all +subterms of $v$ as belonging to the same universe of $v$. If this is +not possible, because the subterm belongs to another universe, then +the default printer that was given as argument to {\tt genprint} is +applied. The default printer is responsible for changing the universe +in a proper way calling the suitable printer for $c$. + +\medskip\noindent {\bf Technical Remark.} In the file +\verb+PPTactic.v+, there are some rules that do not arise from the +inversion of a parsing rule. They are strongly related to the way the +printing is implemented. + +\begin{coq_example*} +Syntax tactic level 8: + constr [(COMMAND $c)] -> [ (PPUNI$COMMAND $c):E ]. +\end{coq_example*} + +As an AST of tactic may have subterms that are commands, these rules +allow the printer of tactic to change the universe. The +\verb+PPUNI$COMMAND+ is a special identifier used for this +purpose. They are used in the code of the default printer that {\tt +gentacpr} gives to {\tt genprint}. + + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/RefMan-tac.tex b/doc/RefMan-tac.tex new file mode 100644 index 000000000..68a50bce7 --- /dev/null +++ b/doc/RefMan-tac.tex @@ -0,0 +1,2172 @@ +\chapter{Tactics} +\index{Tactics} +\label{Tactics} + +A deduction rule is a link between some (unique) formula, that we call +the {\em conclusion} and (several) formul{\ae} that we call the {\em +premises}. Indeed, a deduction rule can be read in two ways. The first +one has the shape: {\it ``if I know this and this then I can deduce +this''}. For instance, if I have a proof of $A$ and a proof of $B$ +then I have a proof of $A \wedge B$. This is forward reasoning from +premises to conclusion. The other way says: {\it ``to prove this I +have to prove this and this''}. For instance, to prove $A \wedge B$, I +have to prove $A$ and I have to prove $B$. This is backward reasoning +which proceeds from conclusion to premises. We say that the conclusion +is {\em the goal}\index{goal} to prove and premises are {\em the +subgoals}\index{subgoal}. The tactics implement {\em backward +reasoning}. When applied to a goal, a tactic replaces this goal with +the subgoals it generates. We say that a tactic reduces a goal to its +subgoal(s). + +Each (sub)goal is denoted with a number. The current goal is numbered +1. By default, a tactic is applied to the current goal, but one can +address a particular goal in the list by writing {\sl n:\tac} which +means {\it ``apply tactic {\tac} to goal number {\sl n}''}. +We can show the list of subgoals by typing {\tt Show} (see section +\ref{Show}). + +Since not every rule applies to a given statement, every tactic cannot be +used to reduce any goal. In other words, before applying a tactic to a +given goal, the system checks that some {\em preconditions} are +satisfied. If it is not the case, the tactic raises an error message. + +Tactics are build from tacticals and atomic tactics. There are, at +least, three levels of atomic tactics. The simplest one implements +basic rules of the logical framework. The second level is the one of +{\em derived rules} which are built by combination of other +tactics. The third one implements heuristics or decision procedures to +build a complete proof of a goal. +%Here is a table of all existing atomic tactics in \Coq: +%\index{atomic tactics} +%\label{atomic-tactics-table} + +\section{Syntax of tactics and tacticals} +\label{tactic-syntax} +\index{tactic@{\tac}} + +A tactic is +applied as an ordinary command. If the tactic does not +address the first subgoal, the command may be preceded by the +wished subgoal number. See figure~\ref{InvokeTactic} for the syntax of +tactic invocation and tacticals. + +\medskip + +\begin{figure} +\begin{center} +\begin{tabular}{|lcl|} +\hline +{\tac} & ::= & \atomictac\\ + & $|$ & {\tt (} {\tac} {\tt )} \\ + & $|$ & {\tac} {\tt Orelse} {\tac}\\ + & $|$ & {\tt Repeat} \tac \\ + & $|$ & {\tt Do} {\num} {\tac} \\ + & $|$ & {\tt Info} \tac \\ + & $|$ & {\tt Try} \tac \\ + & $|$ & {\tt First [} {\tac}{\tt\ | \dots\ | }{\tac} {\tt ]} \\ + & $|$ & {\tt Solve [} {\tac}{\tt\ | \dots\ | }{\tac} {\tt ]} \\ + & $|$ & {\tt Abstract} {\tac} \\ + & $|$ & {\tt Abstract} {\tac} {\tt using} {\ident}\\ + & $|$ & {\tac} {\tt ;} {\tac}\\ + & $|$ & {\tac} {\tt ;[} {\tac} \tt \verb=|= + \dots\ \verb=|= {\tac} {\tt ]} \\ +{\commandtac} & ::= & {\num} {\tt :} {\tac} {\tt .}\\ + & $|$ & {\tac} {\tt .}\\ +\hline +\end{tabular} +\end{center} +\caption{Invocation of tactics and tacticals}\label{InvokeTactic} +\end{figure} + +\begin{Remarks} +\item The infix tacticals {\tt Orelse} and ``\dots\ {\tt ;} \dots'' are +associative. +The tactical {\tt Orelse} binds more than the prefix tacticals +{\tt Try}, {\tt Repeat}, {\tt Do}, {\tt Info} and {\tt Abstract} which +themselves bind more than +the postfix tactical ``{\tt \dots\ ;[ \dots\ ]}'' which +binds more than ``\dots\ {\tt ;} \dots''. + +\noindent For instance + +\noindent {\tt Try Repeat \tac$_1$ Orelse + \tac$_2$;\tac$_3$;[\tac$_{31}$|\dots|\tac$_{3n}$);\tac$_4$)} + +\noindent is understood as + +\noindent {\tt (Try (Repeat (\tac$_1$ Orelse \tac$_2$))); + ((\tac$_3$;[\tac$_{31}$|\dots|\tac$_{3n}$]);\tac$_4$)}. + +\item An {\atomictac} is any of the tactics listed below. +\end{Remarks} + +\section{Explicit proof as a term} + +\subsection{\tt Exact \term} +\tacindex{Exact} +\label{Exact} +This tactic applies to any goal. It gives directly the exact proof +term of the goal. Let {\T} be our goal, let {\tt p} be a term of type +{\tt U} then {\tt Exact p} succeeds iff {\tt T} and {\tt U} are +convertible (see section \ref{conv-rules}). + +\begin{ErrMsgs} +\item \errindex{Not an exact proof} +\end{ErrMsgs} + + +\subsection{\tt Refine \term} +\tacindex{Refine} +\label{Refine} +\index{?@{\texttt{?}}} + +\Rem You need first to require the module {\tt Refine} to use this tactic. + +\noindent +This tactic allows to give an exact proof but still with some +holes. The holes are noted ``\texttt{?}''. + +\begin{ErrMsgs} +\item \errindex{invalid argument}: + the tactic \texttt{Refine} doesn't know what to do + with the term you gave. +\item \texttt{Refine passed ill-formed term}: the term you gave is not + a valid proof (not easy to debug in general). + This message may also occur in higher-level tactics, which call + \texttt{Refine} internally. +\item \errindex{There is an unknown subterm I cannot solve}: + there is a hole in the term you gave + which type cannot be inferred. Put a cast around it. +\end{ErrMsgs} + +This tactic is currently given as an experiment. An example of use is given +in section \ref{Refine-example}. + +\section{Basics} +\index{Typing rules} +Tactics presented in this section implement the basic typing rules of +{\sc Cic} given in chapter \ref{Cic}. + +\subsection{{\tt Assumption}} +\tacindex{Assumption} +This tactic applies to any goal. It implements the +``Var''\index{Typing rules!Var} rule given in section +\ref{Typed-terms}. It looks in the local context for an hypothesis +which type is equal to the goal. If it is the case, the subgoal is +proved. Otherwise, it fails. + +\begin{ErrMsgs} +\item \errindex{No such assumption} +\end{ErrMsgs} + +\subsection{\tt Clear {\ident}.}\tacindex{Clear} +This tactic erases the hypothesis named {\ident} in the local context +of the current goal. Then {\ident} is no more displayed and no more +usable in the proof development. + +\begin{ErrMsgs} +\item {\ident} \errindex{is not among the assumptions.} +\end{ErrMsgs} + +\subsection{\tt Move {\ident$_1$} after {\ident$_2$}.}\tacindex{Move} +This moves the hypothesis named {\ident$_1$} in the local context +after the hypothesis named {\ident$_2$}. + +If {\ident$_1$} comes before {\ident$_2$} in the order of dependences, +then all hypotheses between {\ident$_1$} and {\ident$_2$} which +(possibly indirectly) depend on {\ident$_1$} are moved also. + +If {\ident$_1$} comes after {\ident$_2$} in the order of dependences, +then all hypotheses between {\ident$_1$} and {\ident$_2$} which +(possibly indirectly)) occur in {\ident$_1$} are moved also. + +\begin{ErrMsgs} +\item \errindex{Cannot move {\ident$_1$} after {\ident$_2$}: + it occurs in {\ident$_2$}} +\item \errindex{Cannot move {\ident$_1$} after {\ident$_2$}: + it depends on {\ident$_2$}} +\end{ErrMsgs} + +\subsection{\tt Intro} +\tacindex{Intro} +\label{Intro} +This tactic applies to a goal which is a product. It implements the +``Lam''\index{Typing rules!Lam} rule given in section +\ref{Typed-terms}. Actually, only one subgoal will be generated since the +other one can be automatically checked. + +If the current goal is a dependent product {\tt (x:T)U} and +{\tt x} is a name that does not exist in the current context, then +{\tt Intro} puts {\tt x:T} in the local context. Otherwise, it puts +{\tt x}{\it n}{\tt :T} where {\it n} is such that {\tt x}{\it n} is a +fresh name. The new subgoal is {\tt U}. If the {\tt x} has been +renamed {\tt x}{\it n} then it is replaced by {\tt x}{\it n} in {\tt +U}. + +If the goal is a non dependent product T -> U, then it +puts in the local context either {\tt H}{\it n}{\tt :T} +(if {\tt T} is {\tt Set} or {\tt Prop}) or {\tt X}{\it n}{\tt :T} (if +the type of {\tt T} is {\tt Type}) or {\tt l}{\it n}{\tt :T} with {\it l} +the first letter of the type of x. {\it n} is such that {\tt H}{\it + n} or {\tt X}{\it n} {\tt l}{\it n} or are fresh identifiers. +In both cases the new subgoal is {\tt U}. + +If the goal is not a product, the tactic {\tt Intro} applies the tactic +{\tt Red} until the tactic {\tt Intro} can be applied or the goal is not +reducible. + +\begin{ErrMsgs} +\item \errindex{No product even after head-reduction} +\end{ErrMsgs} + +\Warning: \texttt{{\ident}$_1$ is already used; changed to {\ident}$_2$} + +\begin{Variants} +\item {\tt Intros}\tacindex{Intros}\\ + Repeats {\tt Intro} until it meets the head-constant. It never reduces + head-constants and it never fails. + +\item {\tt Intro {\ident}}\\ + Applies {\tt Intro} but forces {\ident} to be the name of the + introduced hypothesis. + + \ErrMsg \errindex{name {\ident} is already bound } + + \Rem {\tt Intro} doesn't check the whole current context. Actually, + identifiers declared or defined in required modules can be used as + {\ident} and, in this case, the old {\ident} of the module is no + more reachable. + +\item {\tt Intros \ident$_1$ \dots\ \ident$_n$} \\ + Is equivalent to the composed tactic {\tt Intro \ident$_1$; \dots\ ; Intro + \ident$_n$}.\\ +More generally, the \texttt{Intros} tactic takes a pattern as argument + in order to introduce names for components of an inductive + definition, it will be explained in~\ref{Intros-pattern}. +\item {\tt Intros until {\ident}} + \tacindex{Intros until}\\ + Repeats {\tt Intro} until it meets a premise of the goal having form + {\tt (} {\ident}~{\tt :}~{\term} {\tt )} + and discharges the variable named {\ident} of + the current goal. + + \ErrMsg \errindex{No such hypothesis in current goal}\\ + +\item {\tt Intros until {\num}} + \tacindex{Intros until}\\ + Repeats {\tt Intro} until the {\num}-th non-dependant premise. For instance, + on the subgoal \verb+(x,y:nat)x=y->(z:nat)h=x->z=y+ the tactic + \texttt{Intros until 2} is equivalent to \texttt{Intros x y H z H0} (assuming + \texttt{x, y, H, z} and \texttt{H0} do not already occur in context). + + \ErrMsg \errindex{No such hypothesis in current goal}\\ + Happens when {\num} is 0 or is greater than the number of non-dependant + products of the goal. + +\item {\tt Intro after \ident} + \tacindex{Intro after}\\ + Applies {\tt Intro} but puts the introduced + hypothesis after the hypothesis \ident{} in the hypotheses. + +\begin{ErrMsgs} +\item \errindex{No product even after head-reduction} +\item \errindex{No such hypothesis} : {\ident} +\end{ErrMsgs} + +\item {\tt Intro \ident$_1$ after \ident$_2$} + \tacindex{Intro ... after}\\ + Behaves as previously but \ident$_1$ is the name of the introduced + hypothesis. + It is equivalent to {\tt Intro \ident$_1$; Move \ident$_1$ after \ident$_2$}. + +\begin{ErrMsgs} +\item \errindex{No product even after head-reduction} +\item \errindex{No such hypothesis} : {\ident} +\end{ErrMsgs} +\end{Variants} + +\subsection{\tt Apply \term} +\tacindex{Apply}\label{Apply} +This tactic applies to any goal. +The argument {\term} is a term well-formed in the local context. +The tactic {\tt Apply} tries to match the +current goal against the conclusion of the type of {\term}. If it +succeeds, then the tactic returns as many subgoals as the +instantiations of the premises of the type of +{\term}. + +\begin{ErrMsgs} +\item \errindex{Impossible to unify \dots\ with \dots} \\ + Since higher order unification is undecidable, the {\tt Apply} + tactic may fail when you think it should work. In this case, if you + know that the conclusion of {\term} and the current goal are + unifiable, you can help the {\tt Apply} tactic by transforming your + goal with the {\tt Change} or {\tt Pattern} tactics (see sections + \ref{Pattern}, \ref{Change}). + +\item \errindex{Cannot refine to conclusions with meta-variables}\\ + This occurs when some instantiations of premises of {\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{ErrMsgs} + +\begin{Variants} +\item{\tt Apply {\term} with {\term$_1$} \dots\ {\term$_n$}} + \tacindex{Apply \dots\ with}\\ + Provides {\tt Apply} with explicit instantiations for all dependent + premises of the type of {\term} which do not occur in the + conclusion and consequently cannot be found by unification. Notice + that {\term$_1$} \dots\ {\term$_n$} must be given according to the order + of these dependent premises of the type of {\term}. + + \ErrMsg \errindex{Not the right number of missing arguments} + +\item{\tt Apply {\term} with {\vref$_1$} := {\term$_1$} \dots\ {\vref$_n$} + := {\term$_n$}} \\ + This also provides {\tt Apply} with values for instantiating + premises. But variables are referred by names and non dependent + products by order (see syntax in the section~\ref{Binding-list}). + +\item{\tt EApply \term}\tacindex{EApply}\label{EApply}\\ + The tactic {\tt EApply} behaves as {\tt Apply} but does not fail when + no instantiation are deducible for some variables in the premises. + Rather, it turns these variables into so-called existential variables + which are variables still to instantiate. An existential variable is + identified by a name of the form {\tt ?$n$} where $n$ is a number. + The instantiation is intended to be found later in the proof. + + An example of use of {\tt EApply} is given in section + \ref{EApply-example}. + +\item{\tt LApply {\term}} \tacindex{LApply} \\ + + This tactic applies to any goal, say {\tt G}. The argument {\term} + has to be well-formed in the current context, its type being + reducible to a non-dependent product {\tt A -> B} with {\tt B} + possibly containing products. Then it generates two subgoals {\tt + B->G} and {\tt A}. Applying {\tt LApply H} (where {\tt H} has type + {\tt A->B} and {\tt B} does not start with a product) does the same + as giving the sequence {\tt Cut B. 2:Apply H.} where {\tt Cut} is + described below. + + \Warning Be careful, when {\term} contains more than one non + dependent product the tactic {\tt LApply} only takes into account the + first product. + +\end{Variants} + +\subsection{\tt Let {\ident} {\tt :=} {\term} {\tt in} + {\tt Goal}}\tacindex{Let} + +This replaces {\term} by {\ident} in the goal and add the +equality {\ident {\tt =} \term} in the local context. + +\begin{Variants} +\item {\tt Let {\ident$_0$} {\tt :=} {\term} {\tt in} {\ident$_1$}} + +This behaves the same but substitutes {\term} not in the goal but in +the hypothesis named {\ident$_1$}. + +\item {\tt Let {\ident$_0$} {\tt :=} {\term} {\tt in} {\num$_1$} \dots\ +{\num$_n$} {\ident$_1$}} + +This notation allows to specify which occurrences of the hypothesis +named {\ident$_1$} (or the goal if {\ident$_1$} is +the word {\tt Goal}) should be substituted. The occurrences are numbered +from left to right. A negative occurrence number means an occurrence +which should not be substituted. + +\item {\tt Let {\ident$_0$} {\tt :=} {\term} {\tt in} {\num$_1^1$} \dots\ +{\num$_{n_1}^1$} {\ident$_1$} \dots {\num$_1^m$} \dots\ +{\num$_{n_m}^m$} {\ident$_m$}} + +This is the general form. It substitutes {\term} at occurrences +{\num$_1^i$} \dots\ {\num$_{n_i}^i$} of hypothesis {\ident$_i$}. One +of the {\ident}'s may be the word {\tt Goal}. +\end{Variants} + +\subsection{\tt Cut {\form}}\tacindex{Cut} +This tactic applies to any goal. It implements the +``App''\index{Typing rules!App} rule given in section +\ref{Typed-terms}. {\tt Cut U} transforms the current goal \texttt{T} +into the two following subgoals: {\tt U -> T} and \texttt{U}. + +\begin{ErrMsgs} +\item \errindex{Not a proposition or a type}\\ + Arises when the argument {\form} is neither of type {\tt Prop}, {\tt + Set} nor {\tt Type}. +\end{ErrMsgs} + +% +% PAS CLAIR; +% DEVRAIT AU MOINS FAIRE UN INTRO; +% DEVRAIT ETRE REMPLACE PAR UN LET; +% MESSAGE D'ERREUR STUPIDE +% POURQUOI Specialize trans_equal ECHOUE ? +%\begin{Variants} +%\item {\tt Specialize \term} +% \tacindex{Specialize} \\ +% The argument {\tt t} should be a well-typed +% term of type {\tt T}. This tactics is to make a cut of a +% proposition when you have already the proof of this proposition +% (for example it is a theorem applied to variables of local +% context). It is equivalent to {\tt Cut T. 2:Exact t}. +% +%\item {\tt Specialize {\term} with \vref$_1$ := {\term$_1$} \dots +% \vref$_n$ := \term$_n$} +% \tacindex{Specialize \dots\ with} \\ +% It is to provide the tactic with some explicit values to instantiate +% premises of {\term} (see section \ref{Binding-list}). +% Some other premises are inferred using type information and +% unification. The resulting well-formed +% term being {\tt (\term~\term'$_1$\dots\term'$_k$)} +% this tactic behaves as is used as +% {\tt Specialize (\term~\term'$_1$\dots\term'$_k$)} \\ +% +% \ErrMsg {\tt Metavariable wasn't in the metamap} \\ +% Arises when the information provided in the bindings list is not +% sufficient. +%\item {\tt Specialize {\num} {\term} with \vref$_1$ := {\term$_1$} \dots\ +% \vref$_n$:= \term$_n$}\\ +% The behavior is the same as before but only \num\ premises of +% \term\ will be kept. +%\end{Variants} + +\subsection{\tt Generalize \term} +\tacindex{Generalize}\label{Generalize} +This tactic applies to any goal. It generalizes the conclusion w.r.t. one +subterm of it. For example: + +\begin{coq_eval} +Goal (x,y:nat) (le O (plus (plus x y) y)). +Intros. +\end{coq_eval} +\begin{coq_example} +Show. +Generalize (plus (plus x y) y). +\end{coq_example} + +\begin{coq_eval} +Abort. +\end{coq_eval} + +If the goal is $G$ and $t$ is a subterm of type $T$ +in the goal, then {\tt Generalize} \textit{t} replaces the goal by {\tt +(x:$T$)$G'$} where $G'$ is obtained from $G$ by replacing all +occurrences of $t$ by {\tt x}. The name of the variable (here {\tt x}) +is chosen accordingly to $T$. + +\begin{Variants} +\item {\tt Generalize \term$_1$ \dots\ \term$_n$} \\ + Is equivalent to {\tt Generalize \term$_n$; \dots\ ; Generalize + \term$_1$}. Note that the sequence of \term$_i$'s are processed from + $n$ to $1$. + +\item {\tt Generalize Dependent \term} \\ +\tacindex{Generalize Dependent} + This generalizes {\term} but + also {\em all} hypotheses which depend on {\term}. + +\end{Variants} + +\subsection{\tt Change \term} +\tacindex{Change}\label{Change} +This tactic applies to any goal. It implements the rule +``Conv''\index{Typing rules!Conv} given in section \ref{Conv}. +{\tt Change U} replaces the current goal \T\ with a \U\ providing +that \U\ is well-formed and that \T\ and \U\ are +convertible. + +\begin{ErrMsgs} +\item \errindex{convert-concl rule passed non-converting term} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Change {\term} in {\ident}}\\ + \tacindex{Change \dots\ in} + This applies the {\tt Change} tactic not to the goal but to the + hypothesis {\ident}. +\end{Variants} + +\SeeAlso \ref{Conversion-tactics} + +\subsection{Bindings list} +\index{Binding list}\label{Binding-list} +\index[tactic]{Binding list} +A bindings list is generally used after the keyword {\tt with} in +tactics. The general shape of a bindings list is {\tt \vref$_1$ := + \term$_1$ \dots\ \vref$_n$ := \term$_n$} where {\vref} is either an +{\ident} or a {\num}. It is used to provide a tactic with a list of +values (\term$_1$, \dots, \term$_n$) that have to be substituted +respectively to \vref$_1$, \dots, \vref$_n$. For all $i \in [1\dots\ n]$, if +\vref$_i$ is \ident$_i$ then it references the dependent product {\tt + \ident$_i$:T} (for some type \T); if \vref$_i$ is \num$_i$ then it +references the \num$_i$-th non dependent premise. + +A bindings list can also be a simple list of terms {\tt \term$_1$ +\term$_2$ \dots\term$_n$}. In that case the references to which these +terms correspond are determined by the tactic. In case of {\tt Elim +\term} (see section \ref{Elim}) the terms should correspond to all the dependent products in +the type of \term\ while in the case of {\tt Apply \term} only the +dependent products which are not bound in the conclusion of the type +are given. + + +\section{Negation and contradiction} + +\subsection{\tt Absurd \term} +\tacindex{Absurd}\label{Absurd} + +This tactic applies to any goal. The argument {\term} is any +proposition {\tt P} of type {\tt Prop}. This tactic applies {\tt +False} elimination, that is it deduces the current goal from {\tt False}, +and generates as +subgoals {\tt $\sim$P} and {\tt P}. It is very useful in proofs by +cases, where some cases are impossible. In most cases, +\texttt{P} or $\sim$\texttt{P} is one of the hypotheses of the local +context. + +\subsection{\tt Contradiction} +\label{Contradiction} +\tacindex{Contradiction} + +This tactic applies to any goal. The {\tt Contradiction} tactic +attempts to find in the current context (after all {\tt Intros}) one +which is equivalent to {\tt False}. It permits to prune irrelevant +cases. This tactic is a macro for the tactics sequence {\tt Intros; + ElimType False; Assumption}. + +\begin{ErrMsgs} +\item \errindex{No such assumption} +\end{ErrMsgs} + + +\section{Conversion tactics} +\index{Conversion tactics} +\index[tactic]{Conversion tactics} +\label{Conversion-tactics} + +This set of tactics implements different specialized usages of the +tactic \texttt{Change}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%voir reduction__conv_x : histoires d'univers. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{{\tt Cbv} \flag$_1$ \dots\ \flag$_n$, {\tt Lazy} \flag$_1$ +\dots\ \flag$_n$ and {\tt Compute}} +\tacindex{Cbv}\tacindex{Lazy} + +These parameterized reduction tactics apply to any goal and perform +the normalization of the goal according to the specified flags. Since +the reduction considered in \Coq\ include $\beta$ (reduction of +functional application), $\delta$ (unfolding +of transparent constants, see \ref{Transparent}) +and $\iota$ (reduction of {\tt Cases}, {\tt Fix} and {\tt +CoFix} expressions), every flag is one of {\tt Beta}, {\tt Delta}, +{\tt Iota}, {\tt [\ident$_1$\ldots\ident$_k$]} and +{\tt -[\ident$_1$\ldots\ident$_k$]}. +The last two flags give the list of +constants to unfold, or the list of constants not to unfold. These two +flags can occur only after the {\tt Delta} flag. The goal may be +normalized with two strategies: {\em lazy} ({\tt Lazy} tactic), or +{\em call-by-value} ({\tt Cbv} tactic). + +The lazy strategy is a call-by-need strategy, with sharing of +reductions: the arguments of a function call are partially evaluated +only when necessary, but if an argument is used several times, it is +computed only once. This reduction is efficient for reducing +expressions with dead code. For instance, the proofs of a proposition +$\exists_T ~x. P(x)$ reduce to a pair of a witness $t$, and a proof +that $t$ verifies the predicate $P$. Most of the time, $t$ may be +computed without computing the proof of $P(t)$, thanks to the lazy +strategy. + +The call-by-value strategy is the one used in ML languages: the +arguments of a function call are evaluated first, using a weak +reduction (no reduction under the $\lambda$-abstractions). Despite the +lazy strategy always performs fewer reductions than the call-by-value +strategy, the latter should be preferred for evaluating purely +computational expressions (i.e. with few dead code). + +\begin{Variants} +\item {\tt Compute}\\ + \tacindex{Compute} + This tactic is an alias for {\tt Cbv Beta Delta Iota}. +\end{Variants} + +\begin{ErrMsgs} +\item \errindex{Delta must be specified before}\\ + A list of constants appeared before the {\tt Delta} flag. +\end{ErrMsgs} + + +\subsection{{\tt Red}} +\tacindex{Red} +This tactic applies to a goal which have form {\tt (x:T1)\dots(xk:Tk)(c + t1 \dots\ tn)} where {\tt c} is a constant. If {\tt c} is transparent +then it replaces {\tt c} with its definition (say {\tt t}) and then +reduces {\tt (t t1 \dots\ tn)} according to $\beta\iota$-reduction rules. + +\begin{ErrMsgs} +\item \errindex{Term not reducible} +\end{ErrMsgs} + +\subsection{{\tt Hnf}} +\tacindex{Hnf} +This tactic applies to any goal. It replaces the current goal with its +head normal form according to the $\beta\delta\iota$-reduction +rules. {\tt Hnf} does not produce a real head normal form but either a +product or an applicative term in head normal form or a variable. + +\Example +The term \verb+(n:nat)(plus (S n) (S n))+ is not reduced by {\tt Hnf}. + +\Rem The $\delta$ rule will only be applied to transparent constants +(i.e. which have not been frozen with an {\tt Opaque} command; see +section \ref{Opaque}). + +\subsection{\tt Simpl} +\tacindex{Simpl} +This tactic applies to any goal. The +tactic {\tt Simpl} first applies $\beta\iota$-reduction rule. +Then it expands transparent constants and tries to reduce {\tt T'} +according, once more, to +$\beta\iota$ rules. But when the $\iota$ rule is not applicable then +possible $\delta$-reductions are not applied. For instance trying to +use {\tt Simpl} on {\tt (plus n O)=n} will change nothing. + +\subsection{\tt Unfold \ident} +\tacindex{Unfold}\label{Unfold} +This tactic applies to any goal. The argument {\ident} must be the +name of a defined transparent constant (see section +\ref{Simpl-definitions} and \ref{Transparent}). +The tactic {\tt Unfold} applies the +$\delta$ rule to each occurrence of {\ident} in the current goal and +then replaces it with its $\beta\iota$-normal form. + +\Warning If the constant is opaque, nothing will happen and no warning +is printed. +\begin{ErrMsgs} +\item {\ident} \errindex{does not occur} +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Unfold {\ident}$_1$ \dots\ \ident$_n$}\\ + \tacindex{Unfold \dots\ in} + Replaces {\em simultaneously} {\ident}$_1$, \dots, {\ident}$_n$ with + their definitions and replaces the current goal with its + $\beta\iota$ normal form. +\item {\tt Unfold \num$_1^1$ \dots\ \num$_i^1$ {\ident}$_1$ \dots\ \num$_1^n$ + \dots\ \num$_j^n$ \ident$_n$}\\ + The lists \num$_1^1$, \dots, \num$_i^1$ and \num$_1^n$, \dots, \num$_j^n$ + are to specify the occurrences of {\ident}$_1$, \dots, \ident$_n$ to be + unfolded. Occurrences are located from left to right in the linear + notation of terms.\\ + \ErrMsg {\tt bad occurrence numbers of {\ident}$_i$} +\end{Variants} + +\subsection{{\tt Fold} \term} +\tacindex{Fold} + +This tactic applies to any goal. \term\ is reduced using the {\tt Red} +tactic. Every occurrence of the resulting term in the goal is then +substituted for \term. + +\begin{Variants} +\item {\tt Fold} \term$_1$ \dots\ \term$_n$ \\ + Equivalent to {\tt Fold} \term$_1${\tt;}\ldots{\tt; Fold} \term$_n$. +\end{Variants} + +\subsection{{\tt Pattern {\term}}} +\tacindex{Pattern}\label{Pattern} +This command applies to any goal. The argument {\term} must be a free +subterm of the current goal. The command {\tt Pattern} performs +$\beta$-expansion (the inverse of $\bt$-reduction) +of the current goal (say \T) by +\begin{enumerate} +\item replacing all occurrences of {\term} in {\T} with a fresh variable +\item abstracting this variable +\item applying the abstracted goal to {\term} +\end{enumerate} +For instance, if the current goal {\T} is {\tt (P t)} when {\tt t} does not occur in +{\tt P} then {\tt Pattern t} transforms it into {\tt ([x:A](P x) t)}. This +command has to be used, for instance, when an {\tt Apply} command +fails on matching. + +\begin{Variants} +\item {\tt Pattern {\num$_1$} \dots\ {\num$_n$} {\term}}\\ + Only the occurrences {\num$_1$} \dots\ {\num$_n$} of {\term} will be + considered for $\beta$-expansion. Occurrences are located from left + to right. +\item {\tt Pattern {\num$_1^1$} \dots\ {\num$_{n_1}^1$} {\term$_1$} \dots + {\num$_1^m$} \dots\ {\num$_{n_m}^m$} {\term$_m$}}\\ + Will process occurrences \num$_1^1$, \dots, \num$_i^1$ of \term$_1$, + \dots, \num$_1^m$, \dots, \num$_j^m$ of \term$_m$ starting from \term$_m$. + Starting from a goal {\tt (P t$_1$\dots\ t$_m$)} with the {\tt + t$_i$} which do not occur in $P$, the tactic {\tt Pattern + t$_1$\dots\ t$_m$} generates the equivalent goal {\tt + ([x$_1$:A$_1$]\dots\ [x$_m$:A$_m$](P x$_1$\dots\ x$_m$) + t$_1$\dots\ t$_m$)}.\\ + If $t_i$ occurs in one of the generated types A$_j$ these + occurrences will also be considered and possibly abstracted. +\end{Variants} + +\subsection{Conversion tactics applied to hypotheses} + +{\convtactic} {\tt in} \ident$_1$ \dots\ \ident$_n$ \\ +Applies the conversion tactic {\convtactic} to the +hypotheses \ident$_1$, \ldots, \ident$_n$. The tactic {\convtactic} is +any of the conversion tactics listed in this section. + +\begin{ErrMsgs} +\item \errindex{No such hypothesis} : {\ident}. +\end{ErrMsgs} + + +\section{Introductions} +Introduction tactics address goals which are inductive constants. +They are used when one guesses that the goal can be obtained with one +of its constructors' type. + +\subsection{\tt Constructor \num} +\label{Constructor} +\tacindex{Constructor} +This tactic applies to a goal such +that the head of its conclusion is an inductive constant (say {\tt + I}). The argument {\num} must be less or equal to the numbers of +constructor(s) of {\tt I}. Let {\tt ci} be the {\tt i}-th constructor +of {\tt I}, then {\tt Constructor i} is equivalent to {\tt Intros; + Apply ci}. + +\begin{ErrMsgs} +\item \errindex{Not an inductive product} +\item \errindex{Not enough Constructors} +\end{ErrMsgs} + +\begin{Variants} +\item \texttt{Constructor} This tries \texttt{Constructor 1} then + \texttt{Constructor 2}, \dots\ , then \texttt{Constructor} \textit{n} + where \textit{n} if the number of constructors of the head of the + goal. +\item {\tt Constructor \num~with} {\bindinglist} + \tacindex{Constructor \dots\ with}\\ + Let {\tt ci} be the {\tt i}-th constructor of {\tt I}, then {\tt + Constructor i with \bindinglist} is equivalent to {\tt Intros; Apply ci + with \bindinglist}. + + \Warning the terms in the \bindinglist\ are checked + in the context where {\tt Constructor} is executed and not in the + context where {\tt Apply} is executed (the introductions are not + taken into account). +\item {\tt Split}\tacindex{Split}\\ + Applies if {\tt I} has only one constructor, typically in the case + of conjunction $A\wedge B$. It is equivalent to {\tt Constructor 1}. +\item {\tt Exists {\bindinglist}}\tacindex{Exists} \\ + Applies if {\tt I} has only one constructor, for instance in the + case of existential quantification $\exists x\cdot P(x)$. + It is equivalent to {\tt Intros; Constructor 1 with \bindinglist}. +\item {\tt Left}\tacindex{Left}, {\tt Right}\tacindex{Right}\\ + Apply if {\tt I} has two constructors, for instance in the case of + disjunction $A\vee B$. They are respectively equivalent to {\tt + Constructor 1} and {\tt Constructor 2}. +\item {\tt Left \bindinglist}, {\tt Right \bindinglist}, + {\tt Split \bindinglist} \\ + Are equivalent to the corresponding {\tt Constructor $i$ with \bindinglist}. +\end{Variants} + +\section{Eliminations (Induction and Case Analysis)} +Elimination tactics are useful to prove statements by induction or +case analysis. +Indeed, they make use of the elimination (or induction) principles +generated with inductive definitions (see section +\ref{Cic-inductive-definitions}). + +\subsection{\tt Elim \term} +\tacindex{Elim}\label{Elim} +This tactic applies to any goal. The type of the argument +{\term} must be an inductive constant. Then according to the type of +the goal, the tactic {\tt Elim} chooses the right destructor and +applies it (as in the case of the {\tt Apply} tactic). For instance, +assume that our proof context contains {\tt n:nat}, assume that our +current goal is {\tt T} of type {\tt Prop}, then +{\tt Elim n} is equivalent to {\tt Apply nat\_ind with n:=n}. + +\begin{ErrMsgs} +\item \errindex{Not an inductive product} +\item \errindex{Cannot refine to conclusions with meta-variables}\\ As {\tt + Elim} uses {\tt Apply}, see section \ref{Apply} and the variant + {\tt Elim \dots\ with \dots} below. +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Elim \term} also works when the type of {\term} starts with + products and the head symbol is an inductive definition. In that + case the tactic tries both to find an object in the inductive + definition and to use this inductive definition for elimination. In + case of non-dependent products in the type, subgoals are generated + corresponding to the hypotheses. In the case of dependent products, + the tactic will try to find an instance for which the elimination + lemma applies. + +\item {\tt Elim {\term} with \term$_1$ \dots\ \term$_n$} + \tacindex{Elim \dots\ with} \\ + Allows the user to give explicitly the values for dependent + premises of the elimination schema. All arguments must be given.\\ + \ErrMsg \errindex{Not the right number of dependent arguments} +\item{\tt Elim {\term} with {\vref$_1$} := {\term$_1$} \dots\ {\vref$_n$} + := {\term$_n$}} \\ + Provides also {\tt Elim} with values for instantiating premises by + associating explicitly variables (or non dependent products) with + their intended instance. +\item{\tt Elim {\term$_1$} using {\term$_2$}} +\tacindex{Elim \dots\ using} \\ + Allows the user to give explicitly an elimination predicate + {\term$_2$} which is not the standard one for the underlying + inductive type of {\term$_1$}. Each of the {\term$_1$} and {\term$_2$} is + either a simple term or a term with a bindings list (see + \ref{Binding-list}). +\item {\tt ElimType \form}\tacindex{ElimType}\\ + The argument {\form} must be inductively defined. {\tt ElimType I} + is equivalent to {\tt Cut I. Intro H{\rm\sl n}; Elim H{\rm\sl n}; + Clear H{\rm\sl n}} + Therefore the hypothesis {\tt H{\rm\sl n}} will not appear in the + context(s) of the subgoal(s).\\ + Conversely, if {\tt t} is a term of (inductive) type {\tt I} and + which does not occur in the goal then + {\tt Elim t} is equivalent to {\tt ElimType I; 2: Exact t.} + + \ErrMsg \errindex{Impossible to unify \dots\ with \dots} \\ Arises when + {\form} needs to be applied to parameters. + +\item {\tt Induction \ident}\tacindex{Induction}\\ + When {\ident} is a quantified variable of the goal, this is + equivalent to {\tt Intros until {\ident}; Pattern {\ident}; Elim + {\ident}} + + Otherwise, it behaves as a ``user-friendly'' version of {\tt Elim + \ident}: it does not duplicate {\ident} after induction and it + automatically generalizes the hypotheses dependent on {\ident} or + dependent on some atomic arguments of the inductive type of {\ident}. + +\item {\tt Induction {\num}}\\ + Is analogous to {\tt Induction {\ident}} but for the {\num}-th + non-dependent premise of the goal. +\end{Variants} + +\subsection{\tt Case \term}\label{Case}\tacindex{Case} +The tactic {\tt Case} is used to perform case +analysis without recursion. The type of {\term} must be inductively defined. + +\begin{Variants} +\item {\tt Case {\term} with \term$_1$ \dots\ \term$_n$} + \tacindex{Case \dots\ with}\\ + Analogous to {\tt Elim \dots\ with} above. +\item {\tt Destruct \ident}\tacindex{Destruct}\\ + Is equivalent to the tactical {\tt Intros Until \ident; Case \ident}. +\item {\tt Destruct {\num}}\\ + Is equivalent to {\tt Destruct {\ident}} but for the {\num}-th non + dependent premises of the goal. +\end{Variants} + +\subsection{\tt Intros \pattern}\label{Intros-pattern}\tacindex{Intros} + +The tactic {\tt Intros} applied to a pattern performs both +introduction of variables and case analysis in order to give names to +components of an hypothesis. + +A pattern is either: +\begin{itemize} +\item a variable +\item a list of patterns: $p_1~\ldots~p_n$ +\item a disjunction of patterns: {\tt [}$p_1$ {\tt |} {\ldots} {\tt +|} $p_n$ {\tt ]} +\item a conjunction of patterns: {\tt (} $p_1$ {\tt ,} {\ldots} {\tt +,} $p_n$ {\tt )} +\end{itemize} + +The behavior of \texttt{Intros} is defined inductively over the +structure of the pattern given as argument: +\begin{itemize} +\item introduction on a variable behaves like described in~\ref{Intro}; +\item introduction over a +list of patterns $p_1~\ldots~p_n$ is equivalent to the sequence of +introductions over the patterns namely: +\texttt{Intros $p_1$;\ldots; Intros $p_n$}, the goal should start with +at least $n$ products; +\item introduction over a +disjunction of patterns $[p_1~|~~\ldots~|~p_n]$, it +introduces a new variable $X$, its type should be an inductive +definition with $n$ +constructors, then it performs a case analysis over $X$ +(which generates $n$ subgoals), it +clears $X$ and performs on each generated subgoals the corresponding +\texttt{Intros}~$p_i$ tactic; +\item introduction over a +conjunction of patterns $(p_1,\ldots,p_n)$, it +introduces a new variable $X$, its type should be an inductive +definition with $1$ +constructor with (at least) $n$ arguments, then it performs a case +analysis over $X$ +(which generates $1$ subgoal with at least $n$ products), it +clears $X$ and performs an introduction over the list of patterns $p_1~\ldots~p_n$. +\end{itemize} +\begin{coq_example} +Lemma intros_test : (A,B,C:Prop)(A\/(B/\C))->(A->C)->C. +Intros A B C [a|(b,c)] f. +Apply (f a). +Proof c. +\end{coq_example} + +%\subsection{\tt FixPoint \dots}\tacindex{Fixpoint} +%Not yet documented. + +\subsection {\tt Double Induction \num$_1$ \num$_2$} +\tacindex{Double Induction} +This tactic applies to any goal. If the \num$_1$th and \num$_2$th +premises of the goal have an inductive type, then this tactic +performs double induction on these premises. +For instance, if the current goal is \verb+(n,m:nat)(P n m)+ then, +{\tt Double Induction 1 2} yields the four cases with their respective +inductive hypothesis. In particular the case for +\verb+(P (S n) (S m))+ +with the inductive hypothesis about both \verb+n+ and \verb+m+. + +\subsection{\tt Decompose [ {\ident} \dots\ {\idents} ] \term} +\label{Decompose} +\tacindex{Decompose} +This tactic allows to recursively decompose a +complex proposition in order to obtain atomic ones. +Example: + +\begin{coq_eval} +Reset Initial. +\end{coq_eval} +\begin{coq_example} +Lemma ex1: (A,B,C:Prop)(A/\B/\C \/ B/\C \/ C/\A) -> C. +Intros A B C H; Decompose [and or] H; Assumption. +\end{coq_example} +\begin{coq_example*} +Qed. +\end{coq_example*} + +\begin{Variants} + +\item {\tt Decompose Sum \term}\tacindex{Decompose Sum} + This decomposes sum types (like \texttt{or}). +\item {\tt Decompose Record \term}\tacindex{Decompose Record} + This decomposes record types (inductive types with one constructor, + like \texttt{and} and \texttt{exists} and those defined with the + \texttt{Record} macro, see p. \pageref{Record}). +\end{Variants} + +\section{Equality} +These tactics use the equality {\tt +eq:(A:Set)A->A->Prop} defined in file {\tt Logic.v} and the equality +{\tt eqT:(A:Type)A->A->Prop} defined in file {\tt +Logic\_Type.v} (see section \ref{Equality}). They +are simply written {\tt t=u} and {\tt t==u}, +respectively. In the following, the notation {\tt +t=u} will represent either one of these two +equalities. + +\subsection{\tt Rewrite \term} +\label{Rewrite} +\tacindex{Rewrite} +This tactic applies to any goal. The type of {\term} +must have the form + +\texttt{(x$_1$:A$_1$) \dots\ (x$_n$:A$_n$)}\term$_1${\tt =}\term$_2$. + +\noindent Then {\tt Rewrite \term} replaces every occurrence of +\term$_1$ by \term$_2$ in the goal. Some of the variables x$_1$ are +solved by unification, and some of the types \texttt{A}$_1$, \dots, +\texttt{A}$_n$ become new subgoals. + +\Rem In case the type of +\term$_1$ contains occurrences of variables bound in the +type of \term, the tactic tries first to find a subterm of the goal +which matches this term in order to find a closed instance \term$'_1$ +of \term$_1$, and then all instances of \term$'_1$ will be replaced. + +\begin{ErrMsgs} +\item \errindex{No equality here} +\item \errindex{Failed to progress}\\ +This happens if \term$_1$ does not occur in the goal. +\end{ErrMsgs} + +\begin{Variants} +\item {\tt Rewrite -> {\term}}\tacindex{Rewrite ->}\\ + Is equivalent to {\tt Rewrite \term} + +\item {\tt Rewrite <- {\term}}\tacindex{Rewrite <-}\\ + Uses the equality \term$_1${\tt=}\term$_2$ from right to left + +\item {\tt Rewrite {\term} in {\ident}} + \tacindex{Rewrite \dots\ in}\\ + Analogous to {\tt Rewrite {\term}} but rewriting is done in the + hypothesis named {\ident}. + +\item {\tt Rewrite -> {\term} in {\ident}} + \tacindex{Rewrite -> \dots\ in}\\ + Behaves as {\tt Rewrite {\term} in {\ident}}. + +\item {\tt Rewrite <- {\term} in {\ident}}\\ + \tacindex{Rewrite <- \dots\ in} + Uses the equality \term$_1${\tt=}\term$_2$ from right to left to + rewrite in the hypothesis named {\ident}. +\end{Variants} + + +\subsection{\tt CutRewrite -> \term$_1$ = \term$_2$} +\label{CutRewrite} +\tacindex{CutRewrite} + +This tactic acts like {\tt Replace {\term$_1$} with {\term$_2$}} +(see below). + +\subsection{\tt Replace {\term$_1$} with {\term$_2$}} +\tacindex{Replace \dots\ with} +This tactic applies to any goal. It replaces all free occurrences of +{\term$_1$} in the current goal with {\term$_2$} and generates the +equality {\term$_2$}{\tt =}{\term$_1$} as a subgoal. It is equivalent +to {\tt Cut \term$_1$=\term$_2$; Intro H{\sl n}; Rewrite H{\sl n}; + Clear H{\sl n}}. + +%N'existe pas... +%\begin{Variants} +% +%\item {\tt Replace {\term$_1$} with {\term$_2$} in \ident} +% This replaces {\term$_1$} with {\term$_2$} in the hypothesis named +% \ident, and generates the subgoal {\term$_2$}{\tt =}{\term$_1$}. +% \begin{ErrMsgs} +% \item \errindex{No such hypothesis} +% \end{ErrMsgs} +% +%\end{Variants} + +\subsection{\tt Reflexivity} +\label{Reflexivity} +\tacindex{Reflexivity} +This tactic applies to a goal which has the form {\tt t=u}. It checks +that {\tt t} and {\tt u} are convertible and then solves the goal. +It is equivalent to {\tt Apply refl\_equal} (or {\tt Apply + refl\_equalT} for an equality in the \Type universe). + +\begin{ErrMsgs} +\item \errindex{Not a predefined equality} +\item \errindex{Impossible to unify \dots\ With ..} +\end{ErrMsgs} + +\subsection{\tt Symmetry}\tacindex{Symmetry} +This tactic applies to a goal which have form {\tt t=u} +(resp. \texttt{t==u}) and changes it into {\tt u=t} (resp. \texttt{u==t}). + +\subsection{\tt Transitivity \term}\tacindex{Transitivity} +This tactic applies to a goal which have form {\tt t=u} +and transforms it into the two subgoals +{\tt t={\term}} and {\tt {\term}=u}. + +\section{Equality and inductive sets} +We describe in this section some special purpose +tactics dealing with equality and inductive sets or +types. These tactics use the equalities {\tt +eq:(A:Set)A->A->Prop} defined in file {\tt Logic.v} +and {\tt eqT:(A:Type)A->A->Prop} defined in file +{\tt Logic\_Type.v} (see section \ref{Equality}). +They are written {\tt t=u} and {\tt t==u}, +respectively. In the following, unless it is stated +otherwise, the notation {\tt t=u} will represent +either one of these two equalities. + +\subsection{\tt Decide Equality} +\label{DecideEquality} +\tacindex{Decide Equality} +This tactic solves a goal of the form +$(x,y:R)\{x=y\}+\{\verb|~|x=y\}$, where $R$ is an inductive type +such that its constructors do not take proofs or functions as +arguments, nor objects in dependent types. + +\begin{Variants} +\item {\tt Decide Equality {\term}$_1$ {\term}$_2$ }.\\ + Solves a goal of the form {\tt \{}\term$_1${\tt =}\term$_2${\tt +\}+\{\verb|~|}\term$_1${\tt =}\term$_2${\tt \}}. +\end{Variants} + +\subsection{\tt Compare \term$_1$ \term$_2$} +\tacindex{Compare} +This tactic compares two given objects \term$_1$ and \term$_2$ +of an inductive datatype. If $G$ is the current goal, it leaves the sub-goals +\term$_1${\tt =}\term$_2$ {\tt ->} $G$ and \verb|~|\term$_1${\tt =}\term$_2$ +{\tt ->} $G$. The type +of \term$_1$ and \term$_2$ must satisfy the same restrictions as in the tactic +\texttt{Decide Equality}. + +\subsection {\tt Discriminate {\ident}} +\label{Discriminate} +\tacindex{Discriminate} +This tactic proves any goal from an absurd +hypothesis stating that two structurally different terms of an +inductive set are equal. For example, from the hypothesis {\tt (S (S + O))=(S O)} we can derive by absurdity any proposition. Let {\ident} +be a hypothesis of type {\tt{\term$_1$} = {\term$_2$}} in the local +context, {\term$_1$} and {\term$_2$} being elements of an inductive set. +To build the proof, the tactic traverses the normal +forms\footnote{Recall: opaque constants will not be expanded by + $\delta$ reductions} of {\term$_1$} and {\term$_2$} looking for a +couple of subterms {\tt u} and {\tt w} ({\tt u} subterm of the normal +form of {\term$_1$} and {\tt w} subterm of the normal form of +{\term$_2$}), 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. + +\begin{ErrMsgs} +\item {\ident} \errindex{Not a discriminable equality} + occurs when the type of + the specified hypothesis is an equation but does not verify the + expected preconditions. +\item {\ident }\errindex{Not an equation} occurs when the type of the specified + hypothesis is not an equation. +\end{ErrMsgs} + + +\begin{Variants} +\item {\tt Discriminate}\tacindex{Discriminate} \\ + It applies to a goal of the form {\tt + \verb=~={\term$_1$}={\term$_2$}} and it is equivalent to: + {\tt Unfold not; Intro {\ident}} ; {\tt Discriminate + {\ident}}. + + \begin{ErrMsgs} + \item \errindex{goal does not satisfy the expected preconditions}. + \item \errindex{Not a discriminable equality} + \end{ErrMsgs} + +\item {\tt Simple Discriminate} + \tacindex{Simple Discriminate} \\ + This tactic applies to a goal which has the form + \verb=~=\term$_1$=\term$_2$ where {\term$_1$} and {\term$_2$} + belong to an inductive set and $=$ denotes the equality \texttt{eq}. + This tactic proves trivial disequalities such as + {\verb.~O=(S n).} It checks that the head symbols of the head normal + forms of {\term$_1$} and {\term$_2$} are not the same constructor. + When this is the case, the current goal is solved. + + \begin{ErrMsgs} + \item \errindex{Not a discriminable equality} + \end{ErrMsgs} + +\end{Variants} + +\subsection{\tt Injection {\ident}} +\label{Injection} +\tacindex{Injection} +The {\tt Injection} tactic is based on the fact that constructors of +inductive sets are injections. That means that if $c$ is a constructor +of an inductive set, and if $(c~\vec{t_1})$ and $(c~\vec{t_2})$ are two +terms that are equal then $~\vec{t_1}$ and $~\vec{t_2}$ are equal +too. + +If {\ident} is an hypothesis of type {\tt {\term$_1$} = {\term$_2$}}, +then {\tt Injection} behaves as applying injection as deep as possible to +derive the equality of all the subterms of {\term$_1$} and {\term$_2$} +placed in the same positions. For example, from the hypothesis {\tt (S + (S n))=(S (S (S m))} we may derive {\tt n=(S m)}. To use this +tactic {\term$_1$} and {\term$_2$} should be elements of an inductive +set and they should be neither explicitly equal, nor structurally +different. We mean by this that, if {\tt n$_1$} and {\tt n$_2$} are +their respective normal forms, then: +\begin{itemize} +\item {\tt n$_1$} and {\tt n$_2$} should not be syntactically equal, +\item there must not exist any couple of subterms {\tt u} and {\tt w}, + {\tt u} subterm of {\tt n$_1$} and {\tt w} subterm of {\tt n$_2$} , + placed in the same positions and having different constructors as + head symbols. +\end{itemize} +If these conditions are satisfied, then, the tactic derives the +equality of all the subterms of {\term$_1$} and {\term$_2$} placed in +the same positions and puts them as antecedents of the current goal. + +\Example Consider the following goal: + +\begin{coq_example*} +Inductive list : Set := + nil: list | cons: nat-> list -> list. +Variable P : list -> Prop. +\end{coq_example*} +\begin{coq_eval} +Lemma ex: (l:list)(n:nat)(P nil)->(cons n l)=(cons O nil)->(P l). +Intros l n H H0. +\end{coq_eval} +\begin{coq_example} +Show. +Injection H0. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +Beware that \texttt{Injection} yields always an equality in a sigma type +whenever the injected object has a dependent type. + +\begin{ErrMsgs} +\item {\ident} \errindex{is not a projectable equality} + occurs when the type of + the hypothesis $id$ does not verify the preconditions. +\item \errindex{Not an equation} occurs when the type of the + hypothesis $id$ is not an equation. +\end{ErrMsgs} + + +\begin{Variants} +\item{\tt Injection}\tacindex{Injection} \\ + If the current goal is of the form {\tt \verb=~={\term$_1$}={\term$_2$}}, + the tactic computes the head normal form + of the goal and then behaves as the sequence: {\tt Unfold not; Intro + {\ident}; Injection {\ident}}. \\ + + \ErrMsg \errindex{goal does not satisfy the expected preconditions} +\end{Variants} + +\subsection{\tt Simplify\_eq {\ident}} +\tacindex{Simplify\_eq} +\label{Simplify-eq} +Let {\ident} be the name of an hypothesis of type {\tt + {\term$_1$}={\term$_2$}} in the local context. If {\term$_1$} and +{\term$_2$} are structurally different (in the sense described for the +tactic {\tt Discriminate}), then the tactic {\tt Simplify\_eq} behaves as {\tt + Discriminate {\ident}} otherwise it behaves as {\tt Injection + {\ident}}. + +\begin{Variants} +\item{\tt Simplify\_eq} +If the current goal has form $\verb=~=t_1=t_2$, then this tactic does +\texttt{Hnf; Intro {\ident}; Simplify\_eq {\ident}}. +\end{Variants} + +\subsection{\tt Dependent Rewrite -> {\ident}} +\tacindex{Dependent Rewrite ->} +\label{Dependent-Rewrite} +This tactic applies to any goal. If \ident\ has type +\verb+(existS A B a b)=(existS A B a' b')+ +in the local context (i.e. each term of the +equality has a sigma type $\{ a:A~ \&~(B~a)\}$) this tactic rewrites +\verb+a+ into \verb+a'+ and \verb+b+ into \verb+b'+ in the current +goal. This tactic works even if $B$ is also a sigma type. This kind +of equalities between dependent pairs may be derived by the injection +and inversion tactics. + +\begin{Variants} +\item{\tt Dependent Rewrite <- {\ident}} +\tacindex{Dependent Rewrite <-} \\ +Analogous to {\tt Dependent Rewrite ->} but uses the equality from +right to left. +\end{Variants} + +\section{Inversion} +\label{Inversion} + +\subsection{\tt Inversion {\ident}}\tacindex{Inversion} + +Let the type of \ident~ in the local context be $(I~\vec{t})$, +where $I$ is a (co)inductive predicate. Then, +\texttt{Inversion} applied to \ident~ derives for each possible +constructor $c_i$ of $(I~\vec{t})$, {\bf all} the necessary +conditions that should hold for the instance $(I~\vec{t})$ to be +proved by $c_i$. + +\begin{Variants} +\item \texttt{Inversion\_clear} \ident\\ + \tacindex{Inversion\_clear} + That does \texttt{Inversion} and then erases \ident~ from the + context. +\item \texttt{Inversion } \ident~ \texttt{in} \ident$_1$ \dots\ \ident$_n$\\ + \tacindex{Inversion \dots\ in} + Let \ident$_1$ \dots\ \ident$_n$, be identifiers in the local context. This + tactic behaves as generalizing \ident$_1$ \dots\ \ident$_n$, and + then performing \texttt{Inversion}. +\item \texttt{Inversion\_clear} \ident~ \texttt{in} \ident$_1$ \ldots + \ident$_n$\\ + \tacindex{Inversion\_clear \dots\ in} + Let \ident$_1$ \dots\ \ident$_n$, be identifiers in the local context. This + tactic behaves as generalizing \ident$_1$ \dots\ \ident$_n$, and + then performing {\tt Inversion\_clear}. +\item \texttt{Dependent Inversion} \ident~\\ + \tacindex{Dependent Inversion} + That must be used when \ident\ appears in the current goal. + It acts like \texttt{Inversion} and then substitutes \ident\ for the + corresponding term in the goal. +\item \texttt{Dependent Inversion\_clear} \ident~\\ + \tacindex{Dependent Inversion\_clear} + Like \texttt{Dependant Inversion}, except that \ident~ is cleared + from the local context. +\item \texttt{Dependent Inversion } \ident~ \texttt{ with } \term \\ + \tacindex{Dependent Inversion \dots\ with} + This variant allow to give the good generalization of the goal. It + is useful when the system fails to generalize the goal automatically. If + \ident~ has type $(I~\vec{t})$ and $I$ has type + $(\vec{x}:\vec{T})s$, then \term~ must be of type + $I:(\vec{x}:\vec{T})(I~\vec{x})\rightarrow s'$ where $s'$ is the + type of the goal. +\item \texttt{Dependent Inversion\_clear } \ident~ \texttt{ with } \term\\ + \tacindex{Dependent Inversion\_clear \dots\ with} + Like \texttt{Dependant Inversion \dots\ with} but clears \ident from + the local context. +\item \texttt{Inversion} \ident \texttt{ using} \ident$'$ \\ + \tacindex{Inversion \dots\ using} + Let \ident~ have type $(I~\vec{t})$ ($I$ an inductive + predicate) in the local context, and \ident$'$ be a (dependent) inversion + lemma. Then, this tactic refines the current goal with the specified + lemma. +\item \texttt{Inversion} \ident~ \texttt{using} \ident$'$ + \texttt{in} \ident$_1$\dots\ \ident$_n$\\ + \tacindex{Inversion \dots\ using \dots\ in} + This tactic behaves as generalizing \ident$_1$\dots\ \ident$_n$, + then doing \texttt{Inversion}\ident~\texttt{using} \ident$'$. +\item \texttt{Simple Inversion} \ident~\\ + \tacindex{Simple Inversion} + It is a very primitive inversion tactic that derives all the necessary + equalities but it does not simplify the constraints as + \texttt{Inversion} do. +\end{Variants} + +\SeeAlso \ref{Inversion-examples} for detailed examples + +\subsection{\tt Derive Inversion \ident~ with + $(\vec{x}:\vec{T})(I~\vec{t})$ Sort \sort} +\label{Derive-Inversion} +\comindex{Derive Inversion} +\index[tactic]{Derive Inversion@{\tt Derive Inversion}} + +This command generates an inversion principle for the +\texttt{Inversion \dots\ using} tactic. +Let $I$ be an inductive predicate and $\vec{x}$ the variables +occurring in $\vec{t}$. This command generates and stocks the +inversion lemma for the sort \sort~ corresponding to the instance +$(\vec{x}:\vec{T})(I~\vec{t})$ with the name \ident~ in the {\bf +global} environment. When applied it is equivalent to have inverted +the instance with the tactic {\tt Inversion}. + +\begin{Variants} +\item \texttt{Derive Inversion\_clear} \ident~ \texttt{with} + \comindex{Derive Inversion\_clear} + $(\vec{x}:\vec{T})(I~\vec{t})$ \texttt{Sort} \sort~ \\ + \index{Derive Inversion\_clear \dots\ with} + When applied it is equivalent to having + inverted the instance with the tactic \texttt{Inversion} + replaced by the tactic \texttt{Inversion\_clear}. +\item \texttt{Derive Dependent Inversion} \ident~ \texttt{with} + $(\vec{x}:\vec{T})(I~\vec{t})$ \texttt{Sort} \sort~\\ + \comindex{Derive Dependent Inversion} + When applied it is equivalent to having + inverted the instance with the tactic \texttt{Dependent Inversion}. +\item \texttt{Derive Dependent Inversion\_clear} \ident~ \texttt{with} + $(\vec{x}:\vec{T})(I~\vec{t})$ \texttt{Sort} \sort~\\ + \comindex{Derive Dependent Inversion\_clear} + When applied it is equivalent to having + inverted the instance with the tactic \texttt{Dependent Inversion\_clear}. +\end{Variants} + +\SeeAlso \ref{Inversion-examples} for examples + +\subsection{\texttt{Quote} \ident}\tacindex{Quote} +\index[default]2-level approach + +This kind of inversion has nothing to do with the tactic +\texttt{Inversion} above. This tactic does \texttt{Change (\ident\ + t)}, where \texttt{t} is a term build in order to ensure the +convertibility. In other words, it does inversion of the function +\ident. This function must be a fixpoint on a simple recursive +datatype: see \ref{Quote-examples} for the full details. + +\begin{ErrMsgs} +\item \errindex{Quote: not a simple fixpoint}\\ + Happens when \texttt{Quote} is not able to perform inversion properly. +\end{ErrMsgs} + +\begin{Variants} +\item \texttt{Quote {\ident} [ \ident$_1$ \dots \ident$_n$ ]}\\ + All terms that are build only with \ident$_1$ \dots \ident$_n$ will be + considered by \texttt{Quote} as constants rather than variables. +\end{Variants} + +\SeeAlso file \texttt{theories/DEMOS/DemoQuote.v} in the distribution + +\section{Automatizing} +\label{Automatizing} + +\subsection{\tt Auto} +\tacindex{Auto} +This tactic implements a Prolog-like resolution procedure to solve the +current goal. It first tries to solve the goal using the {\tt + Assumption} tactic, then it reduces the goal to an atomic one using +{\tt Intros} and introducing the newly generated hypotheses as hints. +Then it looks at the list of tactics associated to the head symbol of +the goal and tries to apply one of them (starting from the tactics +with lower cost). This process is recursively applied to the generated +subgoals. + +By default, Auto only uses the hypotheses of the current goal and the +hints of the database named "core". + +\begin{Variants} +\item {\tt Auto \num}\\ + Forces the search depth to be \num. The maximal search depth is 5 by default. +\item {\tt Auto with \ident$_1$ \dots\ \ident$_n$}\\ + Uses the hint databases $\ident_1$ \dots\ $\ident_n$ in addition to + the database "core". See section \ref{Hints-databases} for the list + of pre-defined databases and the way to create or extend a database. + This option can be combined with the previous one. +\item {\tt Auto with *}\\ + Uses all existing hint databases, minus the special database + "v62". See section \ref{Hints-databases} +\item {\tt Trivial}\tacindex{Trivial}\\ + This tactic is a restriction of {\tt Auto} that is not recursive and + tries only hints which cost is 0. Typically it solves trivial + equalities like $X=X$. +\item \texttt{Trivial with \ident$_1$ \dots\ \ident$_n$}\\ +\item \texttt{Trivial with *}\\ +\end{Variants} + +\Rem {\tt Auto} either solves completely the goal or else leave it +intact. \texttt{Auto} and \texttt{Trivial} never fail. + +\SeeAlso section \ref{Hints-databases} + +\subsection{\tt EAuto}\tacindex{EAuto}\label{EAuto} + +This tactic generalizes {\tt Auto}. In contrast with +the latter, {\tt EAuto} uses unification of the goal +against the hints rather than pattern-matching +(in other words, it uses {\tt EApply} instead of +{\tt Apply}). +As a consequence, {\tt EAuto} can solve such a goal: + +\begin{coq_example} +Hints Resolve ex_intro. +Goal (P:nat->Prop)(P O)->(EX n | (P n)). +EAuto. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +Note that {\tt ex\_intro} should be declared as an +hint. + +\SeeAlso section \ref{Hints-databases} + +\subsection{\tt Prolog [ \term$_1$ \dots\ \term$_n$ ] \num} +\tacindex{Prolog}\label{Prolog} +This tactic, implemented by Chet Murthy, is based upon the concept of +existential variables of Gilles Dowek, stating that resolution is a +kind of unification. It tries to solve the current goal using the {\tt + Assumption} tactic, the {\tt Intro} tactic, and applying hypotheses +of the local context and terms of the given list {\tt [ \term$_1$ + \dots\ \term$_n$\ ]}. It is more powerful than {\tt Auto} since it +may apply to any theorem, even those of the form {\tt (x:A)(P x) -> Q} +where {\tt x} does not appear free in {\tt Q}. The maximal search +depth is {\tt \num}. + +\begin{ErrMsgs} +\item \errindex{Prolog failed}\\ + The Prolog tactic was not able to prove the subgoal. +\end{ErrMsgs} + +\subsection{\tt Tauto}\tacindex{Tauto}\label{Tauto} +This tactic, due to César Mu\~noz \cite{Mun94}, implements a +decision procedure for intuitionistic propositional calculus based on +the contraction-free sequent calculi LJT* of R. Dyckhoff \cite{Dyc92}. +Note tha + t {\tt Tauto} succeeds on any instance of an intuitionistic +tautological proposition. For instance it succeeds on +\verb!(x:nat)(P:nat->Prop)x=O\/(P x)->~x=O->(P x)! +while {\tt Auto} fails. + +\subsection{\tt Intuition} +\tacindex{Intuition}\label{Intuition} + +The tactic \verb1Intuition1 takes advantage of the search-tree builded +by the decision procedure involved in the tactic {\tt Tauto}. It uses +this information to generate a set of subgoals equivalent to the +original one (but simpler than it) and applies the tactic +{\tt Auto with *} to them \cite{Mun94}. At the end, {\tt Intuition} +performs {\tt Intros}. + +For instance, the tactic {\tt Intuition} applied to the goal +\begin{verbatim} +((x:nat)(P x))/\B->((y:nat)(P y))/\(P O)\/B/\(P O) +\end{verbatim} +internally replaces it by the equivalent one: +\begin{verbatim} +((x:nat)(P x) -> B -> (P O)) +\end{verbatim} +and then uses {\tt Auto with *} which completes the proof. + +\subsection{\tt Linear}\tacindex{Linear}\label{Linear} +The tactic \texttt{Linear}, due to Jean-Christophe Filliâatre +\cite{Fil94}, implements a decision procedure for {\em Direct + Predicate Calculus}, that is first-order Gentzen's Sequent Calculus +without contraction rules \cite{KeWe84,BeKe92}. Intuitively, a +first-order goal is provable in Direct Predicate Calculus if it can be +proved using each hypothesis at most once. + +Unlike the previous tactics, the \texttt{Linear} tactic does not belong +to the initial state of the system, and it must be loaded explicitly +with the command + +\begin{coq_example*} +Require Linear. +\end{coq_example*} + +For instance, assuming that \texttt{even} and \texttt{odd} are two +predicates on natural numbers, and \texttt{a} of type \texttt{nat}, the +tactic \texttt{Linear} solves the following goal + +\begin{coq_eval} +Variables even,odd : nat -> Prop. +Variable a:nat. +\end{coq_eval} + +\begin{coq_example*} +Lemma example : (even a) + -> ((x:nat)((even x)->(odd (S x)))) + -> (EX y | (odd y)). +\end{coq_example*} + +You can find examples of the use of \texttt{Linear} in +\texttt{theories/DEMOS/DemoLinear.v}. +\begin{coq_eval} +Abort. +\end{coq_eval} + +\begin{Variants} +\item {\tt Linear with \ident$_1$ \dots\ \ident$_n$}\\ + \tacindex{Linear with} + Is equivalent to apply first {\tt Generalize \ident$_1$ \dots + \ident$_n$} (see section \ref{Generalize}) then the \texttt{Linear} + tactic. So one can use axioms, lemmas or hypotheses of the local + context with \texttt{Linear} in this way. +\end{Variants} + +\begin{ErrMsgs} +\item \errindex{Not provable in Direct Predicate Calculus} +\item \errindex{Found $n$ classical proof(s) but no intuitionistic one}\\ + The decision procedure looks actually for classical proofs of the + goals, and then checks that they are intuitionistic. In that case, + classical proofs have been found, which do not correspond to + intuitionistic ones. +\end{ErrMsgs} + +\subsection{\tt Omega} +\tacindex{Omega} +\label{Omega} + +The tactic \texttt{Omega}, due to Pierre Crégut, +is an automatic decision procedure for Prestburger +arithmetic. It solves quantifier-free +formulae build with \verb|~|, \verb|\/|, \verb|/\|, +\verb|->| on top of equations and inequations on +both the type \texttt{nat} of natural numbers and \texttt{Z} of binary +integers. This tactic must be loaded by the command \texttt{Require + Omega}. See the additional documentation about \texttt{Omega}. + +\subsection{\tt Ring \term$_1$ \dots\ \term$_n$} +\tacindex{Ring} +\comindex{Add Ring} +\comindex{Add Semi Ring} + +This tactic, written by Samuel Boutin and Patrick Loiseleur, +does AC rewriting on every +ring. The tactic must be loaded by \texttt{Require Ring} under +\texttt{coqtop} or \texttt{coqtop -full}. +The ring must be declared in the \texttt{Add Ring} +command (see \ref{Ring}). The ring of booleans is predefined; if one +wants to use the tactic on \texttt{nat} one must do \texttt{Require + ArithRing}; for \texttt{Z}, do \texttt{Require ZArithRing}. + +\term$_1$, \dots, \term$_n$ must be subterms of the goal +conclusion. \texttt{Ring} normalize these terms +w.r.t. associativity and commutativity and replace them by their +normal form. + +\begin{Variants} +\item \texttt{Ring} When the goal is an equality $t_1=t_2$, it + acts like \texttt{Ring} $t_1$ $t_2$ and then simplifies or solves + the equality. + +\item \texttt{NatRing} is a tactic macro for \texttt{Repeat Rewrite + S\_to\_plus\_one; Ring}. The theorem \texttt{S\_to\_plus\_one} is a + proof that \texttt{(n:nat)(S n)=(plus (S O) n)}. + +\end{Variants} + +\Example +\begin{coq_example*} +Require ZArithRing. +Goal (a,b,c:Z)`(a+b+c)*(a+b+c) + = a*a + b*b + c*c + 2*a*b + 2*a*c + 2*b*c`. +\end{coq_example*} +\begin{coq_example} +Intros; Ring. +\end{coq_example} +\begin{coq_eval} +Reset Initial. +\end{coq_eval} + +You can have a look at the files \texttt{Ring.v}, +\texttt{ArithRing.v}, \texttt{ZarithRing.v} to see examples of the +\texttt{Add Ring} command. + +\SeeAlso \ref{Ring} for more detailed explanations about this tactic + +\subsection{\tt AutoRewrite [{\rewrule} {\dots} {\rewrule}]} +\tacindex{AutoRewrite} + +This tactic carries out rewritings according the given rewriting +rules. + +A \emph{rewriting rule} is, by definition, a list of terms which type is an +equality, each term being followed by the keyword \texttt{LR} (for +left-to-right) or \texttt{RL} (for right-to-left): + +\begin{tabular}{rcl} +\rewrule & ::= & \texttt{[{\term} {\switch} {\dots} {\term} {\switch} ]}\\ +\switch & ::= & \texttt{LR}\\ +\switch & | & \texttt{RL} \\ +\end{tabular} + +\texttt{AutoRewrite} tries each rewriting of each rule, until +it succeeds; then the rewriting is processed and \texttt{AutoRewrite} +tries again all rewritings from the first one. This tactic may not +terminate and warnings are produced every 100 rewritings. + +\begin{Variants} +\item {\tt AutoRewrite [\ident$_1$\dots\ \ident$_n$] +Step=[\tac$_1$|...|\tac$_m$]}\\ +Each time a rewriting rule is successful, it tries to solve with the tactics of +{\tt Step}. + +\item {\tt AutoRewrite [{\rewrule} {\dots} {\rewrule}] +Step=[\tac$_1$|...|\tac$_m$] with Solve}\\ +This is equivalent to the previous variant. + +\item{\tt AutoRewrite [{\rewrule} {\dots} {\rewrule}] +Step=[\tac$_1$|...|\tac$_m$] with Use}\\ +Each time a rewriting rule is successful, it tries to apply a tactic of {\tt +Step}. + +\item{\tt AutoRewrite [{\rewrule} {\dots} {\rewrule}] +Step=[\tac$_1$|...|\tac$_m$] with All}\\ +Each time a rewriting rule is successful, it tries to solve with the tactics of +{\tt Step}, if it fails, it tries to apply a tactic of {\tt Step}. In fact, it +behaves like the {\tt Solve} switch first and the {\tt Use} switch next in case +of failure. + +\item {\tt AutoRewrite [{\rewrule} {\dots} {\rewrule}] +Rest=[\tac$_1$|...|\tac$_m$]}\\ +If subgoals are generated by a conditional rewriting, it tries to solve each of +them with the tactics in {\tt Rest}. + +\item {\tt AutoRewrite [{\rewrule} {\dots} {\rewrule}] +Rest=[\tac$_1$|...|\tac$_m$] with Solve}\\ +This is equivalent to the previous variant. + +\item {\tt AutoRewrite [{\rewrule} {\dots} {\rewrule}] +Rest=[\tac$_1$|...|\tac$_m$] with Cond}\\ +Each time subgoals are generated by a successful conditional rewriting, it +tries to solve all of them, if it fails, it considers that the rewriting rule +fails and takes the next one in the bases. + +\item {\tt AutoRewrite [{\rewrule} {\dots} {\rewrule}] Depth=\num}\\ +Produces a warning giving the number of rewritings carried out every {\num} +rewritings. +\end{Variants} + +The three options {\tt Step}, {\tt Solve} et {\tt Depth} can be combined. + +\subsection{\tt HintRewrite {\ident} {\rewrule}}\comindex{HintRewrite} + +This vernacular command makes an alias for a rewriting rule. +Then, instead of \texttt{AutoRewrite [{\rewrule} \dots ]} you can +type: \texttt{AutoRewrite [{\ident} \dots ]} + +This vernacular command is synchronous with the section mechanism (see +\ref{Section}): when closing a section, all aliases created by +\texttt{HintRewrite} in that section are lost. Conversely, when +loading a module, all \texttt{HintRewrite} declarations at the global +level of that module are loaded. + +\SeeAlso \ref{AutoRewrite-example} for examples showing the use of +this tactic. + +\SeeAlso file \texttt{theories/DEMOS/DemoAutoRewrite.v} + +\section{Developing certified programs} +\label{program} +This section is devoted to powerful tools that \Coq~ provides to +develop certified programs. We just mention below the main features of +those tools and refer the reader to chapter \ref{Addoc-program} and +references \cite{CPar93,CPar95} for more details and examples. + +\subsection{\tt Realizer \term}\tacindex{Realizer} +This command associates the term {\term} to the current goal. The +{\term}'s syntax is described in the chapter \ref{Addoc-program}. +It is an extension of the basic syntax for \Coq's terms. The {\tt + Realizer} is used as a hint by the {\tt Program} tactic described +below. The term {\term} intends to be the program extracted from the +proof we want to develop. + +\SeeAlso chapter \ref{Addoc-program}, section \ref{Extraction} + +\subsection{\tt Program}\tacindex{Program} +This tactic tries to make a one step inference according to the +structure of the {\tt Realizer} associated to the current goal. + +\begin{Variants} +\item {\tt Program\_all}\tacindex{Program\_all}\\ + Is equivalent to {\tt Repeat (Program Orelse Auto with *)} (see section + \ref{Tacticals}). +\end{Variants} + +\SeeAlso chapter \ref{Addoc-program} + +\section{The hints databases for Auto and EAuto} +\index{Hints databases}\label{Hints-databases} +The hints for Auto and EAuto have been reorganized since \Coq{} +6.2.3. They are stored in several databases. Each databases maps head +symbols to list of hints. One can use the command \texttt{Print Hint \ident} +to display the hints associated to the head symbol \ident{} +(see \ref{PrintHint}). Each hint has a name, +a cost that is an nonnegative integer, and a pattern. The hint is +tried by \texttt{Auto} if the conclusion of current goal matches its +pattern, and after hints with a lower cost. The general command to add +a hint to a database is: + +\comindex{Hint} +\begin{quotation} + \texttt{Hint \textsl{name} : \textsl{database} := \textsl{hint\_definition}} +\end{quotation} + +\noindent where {\sl hint\_definition} is one of the following expressions: + +\begin{itemize} +\item \texttt{Resolve} {\term} \index[command]{Hints!Resolve}\\ + This command adds {\tt Apply {\term}} to the hint list + with the head symbol of the type of \term. The cost of that hint is + the number of subgoals generated by {\tt Apply {\term}}. + + In case the inferred type of \term\ does not start with a product the + tactic added in the hint list is {\tt Exact {\term}}. In case this + type can be reduced to a type starting with a product, the tactic {\tt + Apply {\term}} is also stored in the hints list. + + If the inferred type of \term\ does contain a dependent + quantification on a predicate, it is added to the hint list of {\tt + EApply} instead of the hint list of {\tt Apply}. In this case, a + warning is printed since the hint is only used by the tactic {\tt + EAuto} (see \ref{EAuto}). A typical example of hint that is used + only by \texttt{EAuto} is a transitivity lemma. + + \begin{ErrMsgs} + \item \errindex{Bound head variable} \\ + The head symbol of the type of {\term} is a bound variable such + that this tactic cannot be associated to a constant. + \item \term\ \errindex{cannot be used as a hint} \\ + The type of \term\ contains products over variables which do not + appear in the conclusion. A typical example is a transitivity axiom. + In that case the {\tt Apply} tactic fails, and thus is useless. + \end{ErrMsgs} + +\item \texttt{Immediate {\term}} \index[command]{Hints!Immediate}\\ + + This command adds {\tt Apply {\term}; Trivial} to the hint list + associated with the head symbol of the type of \ident in the given + database. This tactic will fail if all the subgoals generated by + {\tt Apply {\term}} are + not solved immediately by the {\tt Trivial} tactic which only tries + tactics with cost $0$. + + This command is useful for theorems such that the symmetry of equality + or $n+1=m+1 \rightarrow n=m$ that we may like to introduce with a + limited use in order to avoid useless proof-search. + + The cost of this tactic (which never generates subgoals) is always 1, + so that it is not used by {\tt Trivial} itself. + + \begin{ErrMsgs} + \item \errindex{Bound head variable}\\ + \item \term\ \errindex{cannot be used as a hint} \\ + \end{ErrMsgs} + +\item \texttt{Constructors} {\ident}\index[command]{Hint!Constructors}\\ + + If {\ident} is an inductive type, this command adds all its + constructors as hints of type \texttt{Resolve}. Then, when the + conclusion of current goal has the form \texttt{({\ident} \dots)}, + \texttt{Auto} will try to apply each constructor. + + \begin{ErrMsgs} + \item {\ident} \errindex{is not an inductive type} + \item {\ident} \errindex{not declared} + \end{ErrMsgs} + +\item \texttt{Unfold} {\ident}\index[command]{Hint!Unfold}\\ + This adds the tactic {\tt Unfold {\ident}} to the hint list + that will only be used when the head constant of the goal is \ident. + Its cost is 4. + +\item \texttt{Extern \num\ \pattern\ }\textsl{tactic}\index[command]{Hints!Extern}\\ + This hint type is to extend Auto with tactics other than + \texttt{Apply} and \texttt{Unfold}. For that, we must specify a + cost, a pattern and a tactic to execute. Here is an example: + +\begin{quotation} +\begin{verbatim} +Hint discr : core := Extern 4 ~(?=?) Discriminate. +\end{verbatim} +\end{quotation} + + Now, when the head of the goal is a disequality, \texttt{Auto} will + try \texttt{Discriminate} if it does not succeed to solve the goal + with hints with a cost less than 4. + + One can even use some sub-patterns of the pattern in the tactic + script. A sub-pattern is a question mark followed by a number like + \texttt{?1} or \texttt{?2}. Here is an example: + +\begin{coq_example*} +Require EqDecide. +Require PolyList. +\end{coq_example*} +\begin{coq_example} +Hint eqdec1 : eqdec := Extern 5 {?1=?2}+{~ (?1=?2)} + Generalize ?1 ?2; Decide Equality. + +Goal (a,b:(list nat*nat)){a=b}+{~a=b}. +Info Auto with eqdec. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\end{itemize} + +\Rem There is currently (in the \coqversion\ release) no way to do +pattern-matching on hypotheses. + +\begin{Variants} +\item \texttt{Hint \ident\ : \ident$_1$ \dots\ \ident$_n$ := + \textsl{hint\_expression}}\\ + This syntax allows to put the same hint in several databases. + + \Rem The current implementation of \texttt{Auto} has no + optimization about hint duplication: + if the same hint is present in two databases + given as arguments to \texttt{Auto}, it will be tried twice. We + recommend to put the same hint in two different databases only if you + never use those databases together. + +\item\texttt{Hint \ident\ := \textsl{hint\_expression}}\\ + If no database name is given, the hint is registered in the "core" + database. + + \Rem We do not recommend to put hints in this database in your + developpements, except when the \texttt{Hint} command + is inside a section. In this case the hint will be thrown when + closing the section (see \ref{Hint-and-Section}) + +\end{Variants} + +There are shortcuts that allow to define several goal at once: + +\begin{itemize} +\item \comindex{Hints Resolve}\texttt{Hints Resolve \ident$_1$ \dots\ \ident$_n$ : \ident.}\\ + This command is a shortcut for the following ones: + \begin{quotation} + \noindent\texttt{Hint \ident$_1$ : \ident\ := Resolve \ident$_1$}\\ + \dots\\ + \texttt{Hint \ident$_1$ : \ident := Resolve \ident$_1$} + \end{quotation} + Notice that the hint name is the same that the theorem given as + hint. +\item \comindex{Hints Immediate}\texttt{Hints Immediate \ident$_1$ \dots\ \ident$_n$ : \ident.}\\ +\item \comindex{Hints Unfold}\texttt{Hints Unfold \ident$_1$ \dots\ \ident$_n$ : \ident.}\\ +\end{itemize} + +%\begin{Warnings} +% \item \texttt{Overriding hint named \dots\ in database \dots} +%\end{Warnings} + +\subsection{Hint databases defined in the \Coq\ standard library} + +Several hint databases are defined in the \Coq\ standard +library. There is no systematic relation between the directories of the +library and the databases. + +\begin{description} +\item[core] This special database is automatically used by + \texttt{Auto}. It contains only basic lemmas about negation, + conjunction, and so on from. Most of the hints in this database come + from the \texttt{INIT} and \texttt{LOGIC} directories. + +\item[arith] This databases contains all lemmas about Peano's + arithmetic proven in the directories \texttt{INIT} and + \texttt{ARITH} + +\item[zarith] contains lemmas about binary signed integers from the + directories \texttt{theories/ZARITH} and + \texttt{tactics/contrib/Omega}. It contains also a hint with a high + cost that calls Omega. + +\item[bool] contains lemmas about booleans, mostly from directory + \texttt{theories/BOOL}. + +\item[datatypes] is for lemmas about about lists, trees, streams and so on that + are proven in \texttt{LISTS}, \texttt{TREES} subdirectories. + +\item[sets] contains lemmas about sets and relations from the + directory \texttt{SETS} and \texttt{RELATIONS}. +\end{description} + +There is also a special database called "v62". It contains all things that are +currently hinted in the 6.2.x releases. It will not be extended later. It is +not included in the hint databases list used in the "Auto with *" tactic. + +The only purpose of the database "v62" is to ensure compatibility for +old developpements with further versions of Coq. +If you have a developpement that used to compile with 6.2.2 and that not +compiles with 6.2.4, try to replace "Auto" with "Auto with v62" using the +script documented below. This will ensure your developpement will compile +will further releases of Coq. + +To write a new developpement, or to update a developpement not finished yet, +you are strongly advised NOT to use this database, but the pre-defined +databases. Furthermore, you are advised not to put your own Hints in the +"core" database, but use one or several databases specific to your +developpement. + +\subsection{\tt Print Hint} +\label{PrintHint} +\comindex{Print Hint} +\index[tactic]{Hints!\texttt{Print Hint}} +This command displays all hints that apply to the current goal. It +fails if no proof is being edited, while the two variants can be used at +every moment. + +\begin{Variants} +\item {\tt Print Hint {\ident} }\\ + This command displays only tactics associated with \ident\ in the + hints list. This is independent of the goal being edited, to this + command will not fail if no goal is being edited. + +\item {\tt Print Hint *}\\ + This command displays all declared hints. +\end{Variants} + + +\subsection{Hints and sections} +\label{Hint-and-Section} + +Like grammar rules and structures for the \texttt{Ring} tactic, things +added by the \texttt{Hint} command will be erased when closing a +section. + +Conversely, when the user does \texttt{Require A.}, all hints +of the module \texttt{A} that are not defined inside a section are +loaded. + +\section{Tacticals} +\index[tactic]{Tacticals}\index{Tacticals}\label{Tacticals} +We describe in this section how to combine the tactics provided by the +system to write synthetic proof scripts called {\em tacticals}. The +tacticals are built using tactic operators we present below. + +\subsection{\tt Idtac} +\tacindex{Idtac} +\index{Tacticals!Idtac@{\tt Idtac}} The constant {\tt Idtac} is the +identity tactic: it leaves any goal unchanged. + +\subsection{\tt Fail} +\tacindex{Fail} +\index{Tacticals!Fail@{\tt Fail}} + +The tactic {\tt Fail} is the always-failing tactic: it does not solve +any goal. It is useful for defining other tacticals. + +\subsection{\tt Do {\num} {\tac}} +\tacindex{Do} +\index{Tacticals!Do@{\tt Do}} +This tactic operator repeats {\num} times the tactic {\tac}. It fails +when it is not possible to repeat {\num} times the tactic. + +\subsection{\tt \tac$_1$ {\tt Orelse} \tac$_2$} +\tacindex{Orelse} +\index{Tacticals!Orelse@{\tt Orelse}} +The tactical \tac$_1$ {\tt Orelse} \tac$_2$ tries to apply \tac$_1$ +and, in case of a failure, applies \tac$_2$. It associates to the +left. + +\subsection{\tt Repeat {\tac}} +\index[tactic]{Repeat@{\tt Repeat}} +\index{Tacticals!Repeat@{\tt Repeat}} + +This tactic operator repeats {\tac} as long as it does not fail. + +\subsection{\tt {\tac}$_1$ {\tt ;} \tac$_2$} +\index{;@{\tt ;}} +\index[tactic]{;@{\tt ;}} +\index{Tacticals!yy@{\tt {\tac$_1$};\tac$_2$}} +This tactic operator is a generalized composition for sequencing. The +tactical {\tac}$_1$ {\tt ;} \tac$_2$ first applies \tac$_1$ and +then applies \tac$_2$ to any +subgoal generated by \tac$_1$. {\tt ;} associates to the left. + +\subsection{\tt \tac$_0$; [ \tac$_1$ | \dots\ | \tac$_n$ ]} +\index[tactic]{;[]@{\tt ;[\ldots$\mid$\ldots$\mid$\ldots]}} +\index{;[]@{\tt ;[\ldots$\mid$\ldots$\mid$\ldots]}} +\index{Tacticals!zz@{\tt {\tac$_0$};[{\tac$_1$}$\mid$\ldots$\mid$\tac$_n$]}} + +This tactic operator is a generalization of the precedent tactics +operator. The tactical {\tt \tac$_0$ ; [ \tac$_1$ | \dots\ | \tac$_n$ ]} +first applies \tac$_0$ and then +applies \tac$_i$ to the i-th subgoal generated by \tac$_0$. It fails if +$n$ is not the exact number of remaining subgoals. + +\subsection{\tt Try {\tac}} +\tacindex{Try} +\index{Tacticals!Try@{\tt Try}} +This tactic operator applies tactic \tac, and catches the possible +failure of \tac. It never fails. + +\subsection{\tt First [ \tac$_0$ | \dots\ | \tac$_n$ ]} +\tacindex{First} +\index{Tacticals!First@{\tt First}} + +This tactic operator tries to apply the tactics \tac$_i$ with $i=0\ldots{}n$, +starting from $i=0$, until one of them does not fail. It fails if all the +tactics fail. + +\begin{ErrMsgs} +\item \errindex{No applicable tactic.} +\end{ErrMsgs} + +\subsection{\tt Solve [ \tac$_0$ | \dots\ | \tac$_n$ ]} +\tacindex{Solve} +\index{Tacticals!First@{\tt Solve}} + +This tactic operator tries to solve the current goal with the tactics \tac$_i$ +with $i=0\ldots{}n$, starting from $i=0$, until one of them solves. It fails if +no tactic can solve. + +\begin{ErrMsgs} +\item \errindex{Cannot solve the goal.} +\end{ErrMsgs} + +\subsection{\tt Info {\tac}} +\tacindex{Info} +\index{Tacticals!Info@{\tt Info}} +This is not really a tactical. For elementary tactics, this is +equivalent to \tac. For complex tactic like \texttt{Auto}, it displays +the operations performed by the tactic. + +\subsection{\tt Abstract {\tac}} +\tacindex{Abstract} +\index{Tacticals!Abstract@{\tt Abstract}} +From outside, typing \texttt{Abstract \tac} is the same that +typing \tac. Internally it saves an auxiliary lemma called +{\ident}\texttt{\_subproof}\textit{n} where {\ident} is the name of the +current goal and \textit{n} is chosen so that this is a fresh name. + +This tactical is useful with tactics such \texttt{Omega} or +\texttt{Discriminate} that generate big proof terms. With that tool +the user can avoid the explosion at time of the \texttt{Save} command +without having to cut ``by hand'' the proof in smaller lemmas. + +\begin{Variants} +\item \texttt{Abstract {\tac} using {\ident}}.\\ + Give explicitly the name of the auxiliary lemma. +\end{Variants} + +\section{Generation of induction principles with {\tt Scheme}} +\label{Scheme} +\comindex{Scheme} + +The {\tt Scheme} command is a high-level tool for generating +automatically (possibly mutual) induction principles for given types +and sorts. Its syntax follows the schema: + +\noindent +{\tt Scheme {\ident$_1$} := Induction for \ident'$_1$ Sort {\sort$_1$} \\ + with\\ + \mbox{}\hspace{0.1cm} \dots\ \\ + with {\ident$_m$} := Induction for {\ident'$_m$} Sort + {\sort$_m$}}\\ + +\ident'$_1$ \dots\ \ident'$_m$ are different inductive type +identifiers belonging to +the same package of mutual inductive definitions. This command +generates {\ident$_1$}\dots{} {\ident$_m$} to be mutually recursive +definitions. Each term {\ident$_i$} proves a general principle +of mutual induction for objects in type {\term$_i$}. + + +\begin{Variants} +\item {\tt Scheme {\ident$_1$} := Minimality for \ident'$_1$ Sort {\sort$_1$} \\ + with\\ + \mbox{}\hspace{0.1cm} \dots\ \\ + with {\ident$_m$} := Minimality for {\ident'$_m$} Sort + {\sort$_m$}}\\ + Same as before but defines a non-dependent elimination principle more + natural in case of inductively defined relations. +\end{Variants} + +\SeeAlso \ref{Scheme-examples} + +\section{Simple tactic macros} +\index[tactic]{tactic macros} +\index{tactic macros} +\comindex{Tactic Definition} +\label{TacticDefinition} + +A simple example has more value than a long explanation: + +\begin{coq_example*} +Tactic Definition Solve := [<:tactic:<Simpl; Intros; Auto>>]. +Tactic Definition ElimBoolRewrite [$b $H1 $H2] := + [<:tactic:<Elim $b; + [Intros; Rewrite $H1; EAuto | Intros; Rewrite $H2; EAuto ]>>]. +\end{coq_example*} + +Those tactic definitions are just macros, they behave like the +syntactic definitions in the tactic world. The right side of the +definition is an AST (see page~\pageref{astsyntax}), +but you can type a command if you +enclose it between \verb|<< >>| or \verb|<:command:< >>|, and you can +type a tactic script (the most frequent case) if you enclose it +between \verb|<:tactic:< >>|. + +The tactics macros are synchronous with the \Coq\ section mechanism: +a \texttt{Tactic Definition} is deleted from the current environment +when you close the section (see also \ref{Section}) +where it was defined. If you want that a +tactic macro defined in a module is usable in the modules that +require it, you should put it outside of any section. + +This command is designed to be simple, so the user who wants to do +complicate things with it should better read the chapter +\ref{WritingTactics} about the user-defined tactics. + + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% TeX-master: "Reference-Manual" +%%% End: + + + diff --git a/doc/RefMan-tacex.tex b/doc/RefMan-tacex.tex new file mode 100644 index 000000000..e41c76ff4 --- /dev/null +++ b/doc/RefMan-tacex.tex @@ -0,0 +1,668 @@ +\chapter{Detailed examples of tactics} +\label{Tactics-examples} + +This chapter presents detailed examples of certain tactics, to +illustrate their behavior. + +\section{\tt Refine} +\tacindex{Refine} +\label{Refine-example} + +This tactic applies to any goal. It behaves like {\tt Exact} with a +big difference : the user can leave some holes (denoted by \texttt{?} or +{\tt (?::}{\it type}{\tt )}) in the term. +{\tt Refine} will generate as many +subgoals as they are holes in the term. The type of holes must be +either synthesized by the system or declared by an +explicit cast like \verb|(?::nat->Prop)|. This low-level +tactic can be useful to advanced users. + +\firstexample +\example{} + +\begin{coq_example*} +Require Refine. +Inductive Option: Set := Fail : Option | Ok : bool->Option. +\end{coq_example} +\begin{coq_example} +Definition get: (x:Option)~x=Fail->bool. +Refine + [x:Option]<[x:Option]~x=Fail->bool>Cases x of + Fail => ? + | (Ok b) => [_:?]b end. +Intros;Absurd Fail=Fail;Trivial. +\end{coq_example} +\begin{coq_example*} +Defined. +\end{coq_example*} + +\example{Using Refine to build a poor-man's ``Cases'' tactic} +\texttt{Refine} is actually the only way for the user to do +a proof with the same structure as a {\tt Cases} definition. Actually, +the tactics \texttt{Case} (see \ref{Case}) and \texttt{Elim} (see +\ref{Elim}) only allow one step of elementary induction. + +\begin{coq_example*} +Require Bool. +Require Arith. +\end{coq_example*} +%\begin{coq_eval} +%Abort. +%\end{coq_eval} +\begin{coq_example} +Definition one_two_or_five := [x:nat] + Cases x of + (1) => true + | (2) => true + | (5) => true + | _ => false + end. +Goal (x:nat)(Is_true (one_two_or_five x)) -> x=(1)\/x=(2)\/x=(5). +\end{coq_example} + +A traditional script would be the following: + +\begin{coq_example*} +Destruct x. +Tauto. +Destruct n. +Auto. +Destruct n0. +Auto. +Destruct n1. +Tauto. +Destruct n2. +Tauto. +Destruct n3. +Auto. +Intros; Inversion H. +\end{coq_example*} + +With the tactic \texttt{Refine}, it becomes quite shorter: + +\begin{coq_example*} +Restart. +Require Refine. +\end{coq_example*} +\begin{coq_example} +Refine [x:nat] + <[y:nat](Is_true (one_two_or_five y))->(y=(1)\/y=(2)\/y=(5))> + Cases x of + (1) => [H]? + | (2) => [H]? + | (5) => [H]? + | _ => [H](False_ind ? H) + end; Auto. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\section{\tt EApply} +\tacindex{EApply} +\label{EApply-example} +\Example +Assume we have a relation on {\tt nat} which is transitive: + +\begin{coq_example*} +Variable R:nat->nat->Prop. +Hypothesis Rtrans : (x,y,z:nat)(R x y)->(R y z)->(R x z). +Variables n,m,p:nat. +Hypothesis Rnm:(R n m). +Hypothesis Rmp:(R m p). +\end{coq_example*} + +Consider the goal {\tt (R n p)} provable using the transitivity of +{\tt R}: + +\begin{coq_example*} +Goal (R n p). +\end{coq_example*} + +The direct application of {\tt Rtrans} with {\tt Apply} fails because +no value for {\tt y} in {\tt Rtrans} is found by {\tt Apply}: + +\begin{coq_example} +Apply Rtrans. +\end{coq_example} + +A solution is to rather apply {\tt (Rtrans n m p)}. + +\begin{coq_example} +Apply (Rtrans n m p). +\end{coq_example} + +\begin{coq_eval} + Undo. +\end{coq_eval} + +More elegantly, {\tt Apply Rtrans with y:=m} allows to only mention +the unknown {\tt m}: + +\begin{coq_example} +Apply Rtrans with y:=m. +\end{coq_example} + +\begin{coq_eval} + Undo. +\end{coq_eval} + +Another solution is to mention the proof of {\tt (R x y)} in {\tt +Rtrans}... + +\begin{coq_example} +Apply Rtrans with 1:=Rnm. +\end{coq_example} + +\begin{coq_eval} + Undo. +\end{coq_eval} + +... or the proof of {\tt (R y z)}: + +\begin{coq_example} +Apply Rtrans with 2:=Rmp. +\end{coq_example} + +\begin{coq_eval} + Undo. +\end{coq_eval} + +On the opposite, one can use {\tt EApply} which postpone the problem +of finding {\tt m}. Then one can apply the hypotheses {\tt Rnm} and {\tt +Rmp}. This instantiates the existential variable and completes the proof. + +\begin{coq_example} +EApply Rtrans. +Apply Rnm. +Apply Rmp. +\end{coq_example} + +\begin{coq_eval} + Reset R. +\end{coq_eval} + +\section{{\tt Scheme}} +\comindex{Scheme} +\label{Scheme-examples} + +\firstexample +\example{Induction scheme for \texttt{tree} and \texttt{forest}} + +The definition of principle of mutual induction for {\tt tree} and +{\tt forest} over the sort {\tt Set} is defined by the command: + +\begin{coq_eval} +Restore State Initial. +Variables A,B:Set. +Mutual Inductive tree : Set := node : A -> forest -> tree +with forest : Set := leaf : B -> forest + | cons : tree -> forest -> forest. +\end{coq_eval} + +\begin{coq_example*} +Scheme tree_forest_rec := Induction for tree Sort Set +with forest_tree_rec := Induction for forest Sort Set. +\end{coq_example*} + +You may now look at the type of {\tt tree\_forest\_rec}: + +\begin{coq_example} +Check tree_forest_rec. +\end{coq_example} + +This principle involves two different predicates for {\tt trees} and +{\tt forests}; it also has three premises each one corresponding to a +constructor of one of the inductive definitions. + +The principle {\tt tree\_forest\_rec} shares exactly the same +premises, only the conclusion now refers to the property of forests. + +\begin{coq_example} +Check forest_tree_rec. +\end{coq_example} + +\example{Predicates {\tt odd} and {\tt even} on naturals} + +Let {\tt odd} and {\tt even} be inductively defined as: + +\begin{coq_eval} +Restore State Initial. +\end{coq_eval} + +\begin{coq_example*} +Mutual Inductive odd : nat->Prop := + oddS : (n:nat)(even n)->(odd (S n)) +with even : nat -> Prop := + evenO : (even O) + | evenS : (n:nat)(odd n)->(even (S n)). +\end{coq_example*} + +The following command generates a powerful elimination +principle: + +\begin{coq_example*} +Scheme odd_even := Minimality for odd Sort Prop +with even_odd := Minimality for even Sort Prop. +\end{coq_example*} + +The type of {\tt odd\_even} for instance will be: + +\begin{coq_example} +Check odd_even. +\end{coq_example} + +The type of {\tt even\_odd} shares the same premises but the +conclusion is {\tt (n:nat)(even n)->(Q n)}. + + +\section{{\tt Inversion}} +\tacindex{Inversion} +\label{Inversion-examples} + +\subsection*{Generalities about inversion} + +When working with (co)inductive predicates, we are very often faced to +some of these situations: +\begin{itemize} +\item we have an inconsistent instance of an inductive predicate in the + local context of hypotheses. Thus, the current goal can be trivially + proved by absurdity. +\item we have a hypothesis that is an instance of an inductive + predicate, and the instance has some variables whose constraints we + would like to derive. +\end{itemize} + +The inversion tactics are very useful to simplify the work in these +cases. Inversion tools can be classified in three groups: + +\begin{enumerate} +\item tactics for inverting an instance without stocking the inversion + lemma in the context; this includes the tactics + (\texttt{Dependent}) \texttt{Inversion} and + (\texttt{Dependent}) \texttt{Inversion\_clear}. +\item commands for generating and stocking in the context the inversion + lemma corresponding to an instance; this includes \texttt{Derive} + (\texttt{Dependent}) \texttt{Inversion} and \texttt{Derive} + (\texttt{Dependent}) \texttt{Inversion\_clear}. +\item tactics for inverting an instance using an already defined + inversion lemma; this includes the tactic \texttt{Inversion \ldots using}. +\end{enumerate} + +As 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. + +\firstexample +\example{Non-dependent inversion} + +Let's consider the relation \texttt{Le} over natural numbers and the +following variables: + +\begin{coq_eval} +Restore State Initial. +\end{coq_eval} + +\begin{coq_example*} +Inductive Le : nat->nat->Set := + LeO : (n:nat)(Le O n) | LeS : (n,m:nat) (Le n m)-> (Le (S n) (S m)). +Variable P:nat->nat->Prop. +Variable Q:(n,m:nat)(Le n m)->Prop. +\end{coq_example*} + +For example, consider the goal: + +\begin{coq_eval} +Lemma ex : (n,m:nat)(Le (S n) m)->(P n m). +Intros. +\end{coq_eval} + +\begin{coq_example} +Show. +\end{coq_example} + +To prove the goal we may need to reason by cases on \texttt{H} and to + derive that \texttt{m} is necessarily of +the form $(S~m_0)$ for certain $m_0$ and that $(Le~n~m_0)$. +Deriving these conditions corresponds to prove that the +only possible constructor of \texttt{(Le (S n) m)} is +\texttt{LeS} and that we can invert the +\texttt{->} in the type of \texttt{LeS}. +This inversion is possible because \texttt{Le} is the smallest set closed by +the constructors \texttt{LeO} and \texttt{LeS}. + +\begin{coq_example} +Inversion_clear H. +\end{coq_example} + +Note that \texttt{m} has been substituted in the goal for \texttt{(S m0)} +and that the hypothesis \texttt{(Le n m0)} has been added to the +context. + +Sometimes it is +interesting to have the equality \texttt{m=(S m0)} in the +context to use it after. In that case we can use \texttt{Inversion} that +does not clear the equalities: + +\begin{coq_example*} +Undo. +\end{coq_example*} + +\begin{coq_example} +Inversion H. +\end{coq_example} + +\begin{coq_eval} +Undo. +\end{coq_eval} + +\example{Dependent Inversion} + +Let us consider the following goal: + +\begin{coq_eval} +Lemma ex_dep : (n,m:nat)(H:(Le (S n) m))(Q (S n) m H). +Intros. +\end{coq_eval} + +\begin{coq_example} +Show. +\end{coq_example} + +As \texttt{H} occurs in the goal, we may want to reason by cases on its +structure and so, we would like inversion tactics to +substitute \texttt{H} by the corresponding term in constructor form. +Neither \texttt{Inversion} nor {\tt Inversion\_clear} make such a +substitution. +To have such a behavior we use the dependent inversion tactics: + +\begin{coq_example} +Dependent Inversion_clear H. +\end{coq_example} + +Note that \texttt{H} has been substituted by \texttt{(LeS n m0 l)} and +\texttt{m} by \texttt{(S m0)}. + +\example{using already defined inversion lemmas} + +\begin{coq_eval} +Abort. +\end{coq_eval} + +For example, to generate the inversion lemma for the instance +\texttt{(Le (S n) m)} and the sort \texttt{Prop} we do: + +\begin{coq_example*} +Derive Inversion_clear leminv with (n,m:nat)(Le (S n) m) Sort Prop. +\end{coq_example*} + +\begin{coq_example} +Check leminv. +\end{coq_example} + +Then we can use the proven inversion lemma: + +\begin{coq_example} +Show. +\end{coq_example} + +\begin{coq_example} +Inversion H using leminv. +\end{coq_example} + +\begin{coq_eval} +Reset Initial. +\end{coq_eval} + +\section{\tt AutoRewrite} +\label{AutoRewrite-example} + +\Example +Here is a basic use of {\tt AutoRewrite} with the Ackermann function: + +\begin{coq_example*} +Require Arith. + +Variable Ack:nat->nat->nat. + +Axiom Ack0:(m:nat)(Ack (0) m)=(S m). +Axiom Ack1:(n:nat)(Ack (S n) (0))=(Ack n (1)). +Axiom Ack2:(n,m:nat)(Ack (S n) (S m))=(Ack n (Ack (S n) m)). +\end{coq_example*} + +\begin{coq_example} +HintRewrite base0 [ Ack0 LR + Ack1 LR + Ack2 LR]. + +Lemma ResAck0:(Ack (2) (1))=(5). +AutoRewrite [base0] Step=[Reflexivity]. +\end{coq_example} + +\begin{coq_eval} +Reset Initial. +\end{coq_eval} + +\Example +The Mac Carthy function shows a more complex case: + +\begin{coq_example*} +Require Omega. + +Variable g:nat->nat->nat. + +Axiom g0:(m:nat)(g (0) m)=m. +Axiom g1: + (n,m:nat)(gt n (0))->(gt m (100))-> + (g n m)=(g (pred n) (minus m (10))). +Axiom g2: + (n,m:nat)(gt n (0))->(le m (100))->(g n m)=(g (S n) (plus m (11))). +\end{coq_example*} + +\begin{coq_example} +HintRewrite base1 [ g0 LR g1 LR]. +HintRewrite base2 [g2 LR]. + +Lemma Resg0:(g (1) (90))=(91). +AutoRewrite [base1 base2] + Step=[Simpl|Reflexivity] with All + Rest=[Omega] with Cond + Depth=10. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +\begin{coq_eval} +Lemma maccarthy_90 : + (g0:(m:nat)(g (0) m)=m) + (g1:(n,m:nat)(gt n (0))->(gt m (100))-> (g n m)=(g (pred n) (minus m (10)))) + (g2:(n,m:nat)(gt n (0))->(le m (100))->(g n m)=(g (S n) (plus m (11)))) + (g (1) (90))=(91). + Intros. +\end{coq_eval} + +One can also give the full base definition instead of a name. This is +useful to do rewritings with the hypotheses of current goal: + +\begin{coq_example} + Show. + AutoRewrite [[g0 LR g1 LR] [g2 LR]] + Step=[Simpl|Reflexivity] with All + Rest=[Omega] with Cond + Depth=10. +\end{coq_example} + +\begin{coq_eval} +Abort. +\end{coq_eval} + +\section{\tt Quote} +\tacindex{Quote} +\label{Quote-examples} + +The tactic \texttt{Quote} allows to use Barendregt's so-called +2-level approach without writing any ML code. Suppose you have a +language \texttt{L} of +'abstract terms' and a type \texttt{A} of 'concrete terms' +and a function \texttt{f : L -> A}. If \texttt{L} is a simple +inductive datatype and \texttt{f} a simple fixpoint, \texttt{Quote f} +will replace the head of current goal a convertible term with the form +\texttt{(f t)}. \texttt{L} must have a constructor of type: \texttt{A + -> L}. + +Here is an example: + +\begin{coq_example} +Require Quote. +Parameters A,B,C:Prop. +Inductive Type formula := +| f_and : formula -> formula -> formula (* binary constructor *) +| f_or : formula -> formula -> formula +| f_not : formula -> formula (* unary constructor *) +| f_true : formula (* 0-ary constructor *) +| f_const : Prop -> formula. (* contructor for constants *) + +Fixpoint interp_f [f:formula] : Prop := + Cases f of + | (f_and f1 f2) => (interp_f f1)/\(interp_f f2) + | (f_or f1 f2) => (interp_f f1)\/(interp_f f2) + | (f_not f1) => ~(interp_f f1) + | f_true => True + | (f_const c) => c + end. + +Goal A/\(A\/True)/\~B/\(A <-> A). +Quote interp_f. +\end{coq_example} + +The algorithm to perform this inversion is: try to match the +term with right-hand sides expression of \texttt{f}. If there is a +match, apply the corresponding left-hand side and call yourself +recursively on sub-terms. If there is no match, we are at a leaf: +return the corresponding constructor (here \texttt{f\_const}) applied +to the term. + +\begin{ErrMsgs} +\item \errindex{Quote: not a simple fixpoint} + Happens when \texttt{Quote} is not able to perform inversion properly. +\end{ErrMsgs} + +\subsection{Introducing variables map} + +The normal use of \texttt{Quote} is to make proofs by reflection: one +defines a function \texttt{simplify : formula -> formula} and proves a +theorem \texttt{simplify\_ok: (f:formula)(interp\_f (simplify f)) -> + (interp\_f f)}. Then, one can simplify formulas by doing: + +\begin{quotation} +\begin{verbatim} + Quote interp_f. + Apply simplify_ok. + Compute. +\end{verbatim} +\end{quotation} + +But there is a problem with leafs: in the example above one cannot +write a function that implements, for example, the logical simplifications +$A \wedge A \ra A$ or $A \wedge \neg A \ra \texttt{False}$. This is +because the \Prop{} is impredicative. + +It is better to use that type of formulas: + +\begin{coq_eval} +Reset formula. +\end{coq_eval} +\begin{coq_example} +Inductive Set formula := +| f_and : formula -> formula -> formula +| f_or : formula -> formula -> formula +| f_not : formula -> formula +| f_true : formula +| f_atom : index -> formula. (* contructor for variables *) +\end{coq_example*} + +\texttt{index} is defined in module \texttt{Quote}. Equality on that +type is decidable so we are able to simplify $A \wedge A$ into $A$ at +the abstract level. + +When there are variables, there are bindings, and \texttt{Quote} +provides also a type \texttt{(varmap A)} of bindings from +\texttt{index} to any set \texttt{A}, and a function +\texttt{varmap\_find} to search in such maps. The interpretation +function has now another argument, a variables map: + +\begin{coq_example} + Fixpoint interp_f [vm:(varmap Prop); f:formula] : Prop := + Cases f of + | (f_and f1 f2) => (interp_f vm f1)/\(interp_f vm f2) + | (f_or f1 f2) => (interp_f vm f1)\/(interp_f vm f2) + | (f_not f1) => ~(interp_f vm f1) + | f_true => True + | (f_atom i) => (varmap_find True i vm) + end. +\end{coq_example} + +\noindent\texttt{Quote} handles this second case properly: + +\begin{coq_example} +Goal A/\(B\/A)/\(A\/~B). +Quote interp_f. +\end{coq_example} + +It builds \texttt{vm} and \texttt{t} such that \texttt{(f vm t)} is +convertible with the conclusion of current goal. + +\subsection{Combining variables and constants} + +One can have both variables and constants in abstracts terms; that is +the case, for example, for the \texttt{Ring} tactic (chapter +\ref{Ring}). Then one must provide to Quote a list of +\emph{constructors of constants}. For example, if the list is +\texttt{[O S]} then closed natural numbers will be considered as +constants and other terms as variables. + +Example: + +\begin{coq_eval} +Reset formula. +\end{coq_eval} +\begin{coq_example*} +Inductive Type formula := +| f_and : formula -> formula -> formula +| f_or : formula -> formula -> formula +| f_not : formula -> formula +| f_true : formula +| f_const : Prop -> formula (* constructor for constants *) +| f_atom : index -> formula. (* constructor for variables *) + +Fixpoint interp_f [vm:(varmap Prop); f:formula] : Prop := + Cases f of + | (f_and f1 f2) => (interp_f vm f1)/\(interp_f vm f2) + | (f_or f1 f2) => (interp_f vm f1)\/(interp_f vm f2) + | (f_not f1) => ~(interp_f vm f1) + | f_true => True + | (f_const c) => c + | (f_atom i) => (varmap_find True i vm) + end. + +Goal A/\(A\/True)/\~B/\(C<->C). +\end{coq_example*} + +\begin{coq_example} +Quote interp_f [A B]. +Undo. Quote interp_f [B C iff]. +\end{coq_example} + +\Warning This tactic is new and experimental. Since function inversion +is undecidable in general case, don't expect miracles from it ! + +\SeeAlso file \texttt{theories/DEMOS/DemoQuote.v} +\SeeAlso comments of source file \texttt{tactics/contrib/polynom/quote.ml} +\SeeAlso the tactic \texttt{Ring} (chapter \ref{Ring}) + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/RefMan-tus.tex b/doc/RefMan-tus.tex new file mode 100755 index 000000000..e4867bf24 --- /dev/null +++ b/doc/RefMan-tus.tex @@ -0,0 +1,1790 @@ +%\documentclass[11pt]{article} +%\usepackage{fullpage,euler} +%\usepackage[latin1]{inputenc} +%\begin{document} +%\title{Writing ad-hoc Tactics in Coq} +%\author{} +%\date{} +%\maketitle +%\tableofcontents +%\clearpage + +\chapter{Writing ad-hoc Tactics in Coq} +\label{WritingTactics} + +\section{Introduction} + +\Coq\ is an open proof environment, in the sense that the collection of +proof strategies offered by the system can be extended by the user. +This feature has two important advantages. First, the user can develop +his/her own ad-hoc proof procedures, customizing the system for a +particular domain of application. Second, the repetitive and tedious +aspects of the proofs can be abstracted away implementing new tactics +for dealing with them. For example, this may be useful when a theorem +needs several lemmas which are all proven in a similar but not exactly +the same way. Let us illustrate this with an example. + +Consider the problem of deciding the equality of two booleans. The +theorem establishing that this is always possible is state by +the following theorem: + +\begin{coq_example*} +Theorem decideBool : (x,y:bool){x=y}+{~x=y}. +\end{coq_example*} + +The proof proceeds by case analysis on both $x$ and $y$. This yields +four cases to solve. The cases $x=y=\textsl{true}$ and +$x=y=\textsl{false}$ are immediate by the reflexivity of equality. + +The other two cases follow by discrimination. The following script +describes the proof: + +\begin{coq_example*} +Destruct x. + Destruct y. + Left ; Reflexivity. + Right; Discriminate. + Destruct y. + Right; Discriminate. + Left ; Reflexivity. +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} + +Now, consider the theorem stating the same property but for the +following enumerated type: + +\begin{coq_example*} +Inductive Set Color := Blue:Color | White:Color | Red:Color. +Theorem decideColor : (c1,c2:Color){c1=c2}+{~c1=c2}. +\end{coq_example*} + +This theorem can be proven in a very similar way, reasoning by case +analysis on $c_1$ and $c_2$. Once more, each of the (now six) cases is +solved either by reflexivity or by discrimination: + +\begin{coq_example*} +Destruct c1. + Destruct c2. + Left ; Reflexivity. + Right ; Discriminate. + Right ; Discriminate. + Destruct c2. + Right ; Discriminate. + Left ; Reflexivity. + Right ; Discriminate. + Destruct c2. + Right ; Discriminate. + Right ; Discriminate. + Left ; Reflexivity. +\end{coq_example*} +\begin{coq_eval} +Abort. +\end{coq_eval} + +If we face the same theorem for an enumerated datatype corresponding +to the days of the week, it would still follow a similar pattern. In +general, the general pattern for proving the property +$(x,y:R)\{x=y\}+\{\neg x =y\}$ for an enumerated type $R$ proceeds as +follow: +\begin{enumerate} +\item Analyze the cases for $x$. +\item For each of the sub-goals generated by the first step, analyze +the cases for $y$. +\item The remaining subgoals follow either by reflexivity or +by discrimination. +\end{enumerate} + +Let us describe how this general proof procedure can be introduced in +\Coq. + +\section{Tactic Macros} + +The simplest way to introduce it is to define it as new a +\textsl{tactic macro}, as follows: + +\begin{coq_example*} +Tactic Definition DecideEq [$a $b] := + [<:tactic:<Destruct $a; + Destruct $b; + (Left;Reflexivity) Orelse (Right;Discriminate)>>]. +\end{coq_example*} + +The general pattern of the proof is abstracted away using the +tacticals ``\texttt{;}'' and \texttt{Orelse}, and introducing two +parameters for the names of the arguments to be analyzed. + +Once defined, this tactic can be called like any other tactic, just +supplying the list of terms corresponding to its real arguments. Let us +revisit the proof of the former theorems using the new tactic +\texttt{DecideEq}: + +\begin{coq_example*} +Theorem decideBool : (x,y:bool){x=y}+{~x=y}. +DecideEq x y. +Defined. +\end{coq_example*} +\begin{coq_example*} +Theorem decideColor : (c1,c2:Color){c1=c2}+{~c1=c2}. +DecideEq c1 c2. +Defined. +\end{coq_example*} + +In general, the command \texttt{Tactic Definition} associates a name +to a parameterized tactic expression, built up from the tactics and +tacticals that are already available. The general syntax rule for this +command is the following: + +\begin{tabbing} +\texttt{Tactic Definition} \textit{tactic-name} \= +\texttt{[}\$$id_1\ldots \$id_n$\texttt{]}\\ +\> := \texttt{[<:tactic:<} \textit{tactic-expression} \verb+>>]+ +\end{tabbing} + +This command provides a quick but also very primitive mechanism for +introducing new tactics. It does not support recursive definitions, +and the arguments of a tactic macro are restricted to term +expressions. Moreover, there is no static checking of the definition +other than the syntactical one. Any error in the definition of the +tactic ---for instance, a call to an undefined tactic--- will not be +noticed until the tactic is called. + +%This command provides a very primitive mechanism for introducing new +%tactics. The arguments of a tactic macro are restricted to term +%expressions. Hence, it is not possible to define higher order tactics +%with this command. Also, there is no static checking of the definition +%other than syntactical. If the tactic contain errors in its definition +%--for instance, a call to an undefined tactic-- this will be noticed +%during the tactic call. + +Let us illustrate the weakness of this way of introducing new tactics +trying to extend our proof procedure to work on a larger class of +inductive types. Consider for example the decidability of equality +for pairs of booleans and colors: + +\begin{coq_example*} +Theorem decideBoolXColor : (p1,p2:bool*Color){p1=p2}+{~p1=p2}. +\end{coq_example*} + +The proof still proceeds by a double case analysis, but now the +constructors of the type take two arguments. Therefore, the sub-goals +that can not be solved by discrimination need further considerations +about the equality of such arguments: + +\begin{coq_example} + Destruct p1; + Destruct p2; Try (Right;Discriminate);Intros. +\end{coq_example} + +The half of the disjunction to be chosen depends on whether or not +$b=b_0$ and $c=c_0$. These equalities can be decided automatically +using the previous lemmas about booleans and colors. If both +equalities are satisfied, then it is sufficient to rewrite $b$ into +$b_0$ and $c$ into $c_0$, so that the left half of the goal follows by +reflexivity. Otherwise, the right half follows by first contraposing +the disequality, and then applying the invectiveness of the pairing +constructor. + +As the cases associated to each argument of the pair are very similar, +a tactic macro can be introduced to abstract this part of the proof: + +\begin{coq_example*} +Hints Resolve decideBool decideColor. +Tactic Definition SolveArg [$t1 $t2] := + [<:tactic:< + ElimType {$t1=$t2}+{~$t1=$t2}; + [(Intro equality;Rewrite equality;Clear equality) | + (Intro diseq; Right; Red; Intro absurd; + Apply diseq;Injection absurd;Trivial) | + Auto]>>]. +\end{coq_example*} + +This tactic is applied to each corresponding pair of arguments of the +arguments, until the goal can be solved by reflexivity: + +\begin{coq_example*} +SolveArg b b0; + SolveArg c c0; + Left; Reflexivity. +Defined. +\end{coq_example*} + +Therefore, a more general strategy for deciding the property +$(x,y:R)\{x=y\}+\{\neg x =y\}$ on $R$ can be sketched as follows: +\begin{enumerate} +\item Eliminate $x$ and then $y$. +\item Try discrimination to solve those goals where $x$ and $y$ has +been introduced by different constructors. +\item If $x$ and $y$ have been introduced by the same constructor, +then iterate the tactic \textsl{SolveArg} for each pair of +arguments. +\item Finally, solve the left half of the goal by reflexivity. +\end{enumerate} + +The implementation of this stronger proof strategy needs to perform a +term decomposition, in order to extract the list of arguments of each +constructor. It also requires the introduction of recursively defined +tactics, so that the \textsl{SolveArg} can be iterated on the lists of +arguments. These features are not supported by the \texttt{Tactic +Definition} command. One possibility could be extended this command in +order to introduce recursion, general parameter passing, +pattern-matching, etc, but this would quickly lead us to introduce the +whole \ocaml{} into \Coq\footnote{This is historically true. In fact, +\ocaml{} is a direct descendent of ML, a functional programming language +conceived language for programming the tactics of the theorem prover +LCF.}. Instead of doing this, we prefer to give to the user the +possibility of writing his/her own tactics directly in \ocaml{}, and then +to link them dynamically with \Coq's code. This requires a minimal +knowledge about \Coq's implementation. The next section provides an +overview of \Coq's architecture. + +%It is important to point out that the introduction of a new tactic +%never endangers the correction of the theorems proven in the extended +%system. In order to understand why, let us introduce briefly the system +%architecture. + +\section{An Overview of \Coq's Architecture} + +The implementation of \Coq\ is based on eight \textsl{logical +modules}. By ``module'' we mean here a logical piece of code having a +conceptual unity, that may concern several \ocaml{} files. By the sake of +organization, all the \ocaml{} files concerning a logical module are +grouped altogether into the same sub-directory. The eight modules +are: + +\begin{tabular}{lll} +1. & The logical framework & (directory \texttt{src/generic})\\ +2. & The language of constructions & (directory \texttt{src/constr})\\ +3. & The type-checker & (directory \texttt{src/typing})\\ +4. & The proof engine & (directory \texttt{src/proofs})\\ +5. & The language of basic tactics & (directory \texttt{src/tactics})\\ +6. & The vernacular interpreter & (directory \texttt{src/env})\\ +7. & The parser and the pretty-printer & (directory \texttt{src/parsing})\\ +8. & The standard library & (directory \texttt{src/lib}) +\end{tabular} + +\vspace{1em} + +The following sections briefly present each of the modules above. +This presentation is not intended to be a complete description of \Coq's +implementation, but rather a guideline to be read before taking a look +at the sources. For each of the modules, we also present some of its +most important functions, which are sufficient to implement a large +class of tactics. + + +\subsection{The Logical Framework} +\label{LogicalFramework} + +At the very heart of \Coq there is a generic untyped language for +expressing abstractions, applications and global constants. This +language is used as a meta-language for expressing the terms of the +Calculus of Inductive Constructions. General operations on terms like +collecting the free variables of an expression, substituting a term for +a free variable, etc, are expressed in this language. + +The meta-language \texttt{'op term} of terms has seven main +constructors: +\begin{itemize} +\item $(\texttt{VAR}\;id)$, a reference to a global identifier called $id$; +\item $(\texttt{Rel}\;n)$, a bound variable, whose binder is the $nth$ + binder up in the term; +\item $\texttt{DLAM}\;(x,t)$, a deBruijn's binder on the term $t$; +\item $\texttt{DLAMV}\;(x,vt)$, a deBruijn's binder on all the terms of + the vector $vt$; +\item $(\texttt{DOP0}\;op)$, a unary operator $op$; +\item $\texttt{DOP2}\;(op,t_1,t_2)$, the application of a binary +operator $op$ to the terms $t_1$ and $t_2$; +\item $\texttt{DOPN} (op,vt)$, the application of an n-ary operator $op$ to the +vector of terms $vt$. +\end{itemize} + +In this meta-language, bound variables are represented using the +so-called deBrujin's indexes. In this representation, an occurrence of +a bound variable is denoted by an integer, meaning the number of +binders that must be traversed to reach its own +binder\footnote{Actually, $(\texttt{Rel}\;n)$ means that $(n-1)$ binders +have to be traversed, since indexes are represented by strictly +positive integers.}. On the other hand, constants are referred by its +name, as usual. For example, if $A$ is a variable of the current +section, then the lambda abstraction $[x:A]x$ of the Calculus of +Constructions is represented in the meta-language by the term: + +\begin{displaymath} +(DOP2 (Lambda,(Var\;A),DLAM (x,(Rel\;1))) +\end{displaymath} + +In this term, $Lambda$ is a binary operator. Its first argument +correspond to the type $A$ of the bound variable, while the second is +a body of the abstraction, where $x$ is bound. The name $x$ is just kept +to pretty-print the occurrences of the bound variable. + +%Similarly, the product +%$(A:Prop)A$ of the Calculus of Constructions is represented by the +%term: +%\begin{displaumath} +%DOP2 (Prod, DOP0 (Sort (Prop Null)), DLAM (Name \#A, Rel 1)) +%\end{displaymath} + +The following functions perform some of the most frequent operations +on the terms of the meta-language: +\begin{description} +\fun{val Generic.subst1 : 'op term -> 'op term -> 'op term} + {$(\texttt{subst1}\;t_1\;t_2)$ substitutes $t_1$ for + $\texttt{(Rel}\;1)$ in $t_2$.} +\fun{val Generic.occur\_var : identifier -> 'op term -> bool} + {Returns true when the given identifier appears in the term, + and false otherwise.} +\fun{val Generic.eq\_term : 'op term -> 'op term -> bool} + {Implements $\alpha$-equality for terms.} +\fun{val Generic.dependent : 'op term -> 'op term -> bool} + {Returns true if the first term is a sub-term of the second.} +%\fun{val Generic.subst\_var : identifier -> 'op term -> 'op term} +% { $(\texttt{subst\_var}\;id\;t)$ substitutes the deBruijn's index +% associated to $id$ to every occurrence of the term +% $(\texttt{VAR}\;id)$ in $t$.} +\end{description} + +\subsubsection{Identifiers, names and sections paths.} + +Three different kinds of names are used in the meta-language. They are +all defined in the \ocaml{} file \texttt{Names}. + +\paragraph{Identifiers.} The simplest kind of names are +\textsl{identifiers}. An identifier is a string possibly indexed by an +integer. They are used to represent names that are not unique, like +for example the name of a variable in the scope of a section. The +following operations can be used for handling identifiers: + +\begin{description} +\fun{val Names.make\_ident : string -> int -> identifier} + {The value $(\texttt{make\_ident}\;x\;i)$ creates the + identifier $x_i$. If $i=-1$, then the identifier has + is created with no index at all.} +\fun{val Names.repr\_ident : identifier -> string * int} + {The inverse operation of \texttt{make\_ident}: + it yields the string and the index of the identifier.} +\fun{val Names.lift\_ident : identifier -> identifier} + {Increases the index of the identifier by one.} +\fun{val Names.next\_ident\_away : \\ +\qquad identifier -> identifier list -> identifier} + {\\ Generates a new identifier with the same root string than the + given one, but with a new index, different from all the indexes of + a given list of identifiers.} +\fun{val Names.id\_of\_string : string -> + identifier} + {Creates an identifier from a string.} +\fun{val Names.string\_of\_id : identifier -> string} + {The inverse operation: transforms an identifier into a string} +\end{description} + +\paragraph{Names.} A \textsl{name} is either an identifier or the +special name \texttt{Anonymous}. Names are used as arguments of +binders, in order to pretty print bound variables. +The following operations can be used for handling names: + +\begin{description} +\fun{val Names.Name: identifier -> Name} + {Constructs a name from an identifier.} +\fun{val Names.Anonymous : Name} + {Constructs a special, anonymous identifier, like the variable abstracted + in the term $[\_:A]0$.} +\fun{val + Names.next\_name\_away\_with\_default : \\ \qquad + string->name->identifier list->identifier} +{\\ If the name is not anonymous, then this function generates a new + identifier different from all the ones in a given list. Otherwise, it + generates an identifier from the given string.} +\end{description} + +\paragraph{Section paths.} +\label{SectionPaths} +A \textsl{section-path} is a global name to refer to an object without +ambiguity. It can be seen as a sort of filename, where open sections +play the role of directories. Each section path is formed by three +components: a \textsl{directory} (the list of open sections); a +\textsl{basename} (the identifier for the object); and a \textsl{kind} +(either CCI for the terms of the Calculus of Constructions, FW for the +the terms of $F_\omega$, or OBJ for other objects). For example, the +name of the following constant: +\begin{verbatim} + Section A. + Section B. + Section C. + Definition zero := O. +\end{verbatim} + +is internally represented by the section path: + +$$\underbrace{\mathtt{\#A\#B\#C}}_{\mbox{dirpath}} +\underbrace{\mathtt{\tt \#zero}}_{\mbox{basename}} +\underbrace{\mathtt{\tt .cci}_{\;}}_{\mbox{kind}}$$ + +When one of the sections is closed, a new constant is created with an +updated section-path,a nd the old one is no longer reachable. In our +example, after closing the section \texttt{C}, the new section-path +for the constant {\tt zero} becomes: +\begin{center} +\texttt{ \#A\#B\#zero.cci} +\end{center} + +The following operations can be used to handle section paths: + +\begin{description} +\fun{val Names.string\_of\_path : section\_path -> string} + {Transforms the section path into a string.} +\fun{val Names.path\_of\_string : string -> section\_path} + {Parses a string an returns the corresponding section path.} +\fun{val Names.basename : section\_path -> identifier} + {Provides the basename of a section path} +\fun{val Names.dirpath : section\_path -> string list} + {Provides the directory of a section path} +\fun{val Names.kind\_of\_path : section\_path -> path\_kind} + {Provides the kind of a section path} +\end{description} + +\subsubsection{Signatures} + +A \textsl{signature} is a mapping associating different informations +to identifiers (for example, its type, its definition, etc). The +following operations could be useful for working with signatures: + +\begin{description} +\fun{val Names.ids\_of\_sign : 'a signature -> identifier list} + {Gets the list of identifiers of the signature.} +\fun{val Names.vals\_of\_sign : 'a signature -> 'a list} + {Gets the list of values associated to the identifiers of the signature.} +\fun{val Names.lookup\_glob1 : \\ \qquad +identifier -> 'a signature -> (identifier * + 'a)} + {\\ Gets the value associated to a given identifier of the signature.} +\end{description} + + +\subsection{The Terms of the Calculus of Constructions} + +The language of the Calculus of Inductive Constructions described in +Chapter \ref{Cic} is implemented on the top of the logical framework, +instantiating the parameter $op$ of the meta-language with a +particular set of operators. In the implementation this language is +called \texttt{constr}, the language of constructions. + +% The only difference +%with respect to the one described in Section \ref{} is that the terms +%of \texttt{constr} may contain \textsl{existential variables}. An +%existential variable is a place holder representing a part of the term +%that is still to be constructed. Such ``open terms'' are necessary +%when building proofs interactively. + +\subsubsection{Building Constructions} + +The user does not need to know the choices made to represent +\texttt{constr} in the meta-language. They are abstracted away by the +following constructor functions: + +\begin{description} +\fun{val Term.mkRel : int -> constr} + {$(\texttt{mkRel}\;n)$ represents deBrujin's index $n$.} + +\fun{val Term.mkVar : identifier -> constr} + {$(\texttt{mkVar}\;id)$ + represents a global identifier named $id$, like a variable + inside the scope of a section, or a hypothesis in a proof}. + +\fun{val Term.mkExistential : constr} + {\texttt{mkExistential} represents an implicit sub-term, like the question + marks in the term \texttt{(pair ? ? O true)}.} + +%\fun{val Term.mkMeta : int -> constr} +% {$(\texttt{mkMeta}\;n)$ represents an existential variable, whose +% name is the integer $n$.} + +\fun{val Term.mkProp : constr} + {$\texttt{mkProp}$ represents the sort \textsl{Prop}.} + +\fun{val Term.mkSet : constr} + {$\texttt{mkSet}$ represents the sort \textsl{Set}.} + +\fun{val Term.mkType : Impuniv.universe -> constr} + {$(\texttt{mkType}\;u)$ represents the term + $\textsl{Type}(u)$. The universe $u$ is represented as a + section path indexed by an integer. } + +\fun{val Term.mkConst : section\_path -> constr array -> constr} + {$(\texttt{mkConst}\;c\;v)$ represents a constant whose name is + $c$. The body of the constant is stored in a global table, + accessible through the name of the constant. The array of terms + $v$ corresponds to the variables of the environment appearing in + the body of the constant when it was defined. For instance, a + constant defined in the section \textsl{Foo} containing the + variable $A$, and whose body is $[x:Prop\ra Prop](x\;A)$ is + represented inside the scope of the section by + $(\texttt{mkConst}\;\texttt{\#foo\#f.cci}\;[| \texttt{mkVAR}\;A + |])$. Once the section is closed, the constant is represented by + the term $(\texttt{mkConst}\;\#f.cci\;[| |])$, and its body + becomes $[A:Prop][x:Prop\ra Prop](x\;A)$}. + +\fun{val Term.mkMutInd : section\_path -> int -> constr array ->constr} + {$(\texttt{mkMutInd}\;c\;i)$ represents the $ith$ type + (starting from zero) of the block of mutually dependent + (co)inductive types, whose first type is $c$. Similarly to the + case of constants, the array of terms represents the current + environment of the (co)inductive type. The definition of the type + (its arity, its constructors, whether it is inductive or co-inductive, etc.) + is stored in a global hash table, accessible through the name of + the type.} + +\fun{val Term.mkMutConstruct : \\ \qquad section\_path -> int -> int -> constr array + ->constr} {\\ $(\texttt{mkMutConstruct}\;c\;i\;j)$ represents the + $jth$ constructor of the $ith$ type of the block of mutually + dependent (co)inductive types whose first type is $c$. The array + of terms represents the current environment of the (co)inductive + type.} + +\fun{val Term.mkCast : constr -> constr -> constr} + {$(\texttt{mkCast}\;t\;T)$ represents the annotated term $t::T$ in + \Coq's syntax.} + +\fun{val Term.mkProd : name ->constr ->constr -> constr} + {$(\texttt{mkProd}\;x\;A\;B)$ represents the product $(x:A)B$. + The free ocurrences of $x$ in $B$ are represented by deBrujin's + indexes.} + +\fun{val Term.mkNamedProd : identifier -> constr -> constr -> constr} + {$(\texttt{produit}\;x\;A\;B)$ represents the product $(x:A)B$, + but the bound occurrences of $x$ in $B$ are denoted by + the identifier $(\texttt{mkVar}\;x)$. The function automatically + changes each occurrences of this identifier into the corresponding + deBrujin's index.} + +\fun{val Term.mkArrow : constr -> constr -> constr} + {$(\texttt{arrow}\;A\;B)$ represents the type $(A\rightarrow B)$.} + +\fun{val Term.mkLambda : name -> constr -> constr -> constr} + {$(\texttt{mkLambda}\;x\;A\;b)$ represents the lambda abstraction + $[x:A]b$. The free ocurrences of $x$ in $B$ are represented by deBrujin's + indexes.} + +\fun{val Term.mkNamedLambda : identifier -> constr -> constr -> constr} + {$(\texttt{lambda}\;x\;A\;b)$ represents the lambda abstraction + $[x:A]b$, but the bound occurrences of $x$ in $B$ are denoted by + the identifier $(\texttt{mkVar}\;x)$. } + +\fun{val Term.mkAppLA : constr array -> constr} + {$(\texttt{mkAppLA}\;t\;[|t_1\ldots t_n|])$ represents the application + $(t\;t_1\;\ldots t_n)$.} + +\fun{val Term.mkMutCaseA : \\ \qquad + case\_info -> constr ->constr + ->constr array -> constr} + {\\ $(\texttt{mkMutCaseA}\;r\;P\;m\;[|f_1\ldots f_n|])$ + represents the term \Case{P}{m}{f_1\ldots f_n}. The first argument + $r$ is either \texttt{None} or $\texttt{Some}\;(c,i)$, where the + pair $(c,i)$ refers to the inductive type that $m$ belongs to.} + +\fun{val Term.mkFix : \\ \qquad +int array->int->constr array->name + list->constr array->constr} + {\\ $(\texttt{mkFix}\;[|k_1\ldots k_n |]\;i\;[|A_1\ldots + A_n|]\;[|f_1\ldots f_n|]\;[|t_1\ldots t_n|])$ represents the term + $\Fix{f_i}{f_1/k_1:A_1:=t_1 \ldots f_n/k_n:A_n:=t_n}$} + +\fun{val Term.mkCoFix : \\ \qquad + int -> constr array -> name list -> + constr array -> constr} + {\\ $(\texttt{mkCoFix}\;i\;[|A_1\ldots + A_n|]\;[|f_1\ldots f_n|]\;[|t_1\ldots t_n|])$ represents the term + $\CoFix{f_i}{f_1:A_1:=t_1 \ldots f_n:A_n:=t_n}$. There are no + decreasing indexes in this case.} +\end{description} + +\subsubsection{Decomposing Constructions} + +Each of the construction functions above has its corresponding +(partial) destruction function, whose name is obtained changing the +prefix \texttt{mk} by \texttt{dest}. In addition to these functions, a +concrete datatype \texttt{kindOfTerm} can be used to do pattern +matching on terms without dealing with their internal representation +in the meta-language. This concrete datatype is described in the \ocaml{} +file \texttt{term.mli}. The following function transforms a construction +into an element of type \texttt{kindOfTerm}: + +\begin{description} +\fun{val Term.kind\_of\_term : constr -> kindOfTerm} + {Destructs a term of the language \texttt{constr}, +yielding the direct components of the term. Hence, in order to do +pattern matching on an object $c$ of \texttt{constr}, it is sufficient +to do pattern matching on the value $(\texttt{kind\_of\_term}\;c)$.} +\end{description} + +Part of the information associated to the constants is stored in +global tables. The following functions give access to such +information: + +\begin{description} +\fun{val Termenv.constant\_value : constr -> constr} + {If the term denotes a constant, projects the body of a constant} +\fun{Termenv.constant\_type : constr -> constr} + {If the term denotes a constant, projects the type of the constant} +\fun{val mind\_arity : constr -> constr} + {If the term denotes an inductive type, projects its arity (i.e., + the type of the inductive type).} +\fun{val Termenv.mis\_is\_finite : mind\_specif -> bool} + {Determines whether a recursive type is inductive or co-inductive.} +\fun{val Termenv.mind\_nparams : constr -> int} + {If the term denotes an inductive type, projects the number of + its general parameters.} +\fun{val Termenv.mind\_is\_recursive : constr -> bool} + {If the term denotes an inductive type, + determines if the type has at least one recursive constructor. } +\fun{val Termenv.mind\_recargs : constr -> recarg list array array} + {If the term denotes an inductive type, returns an array $v$ such + that the nth element of $v.(i).(j)$ is + \texttt{Mrec} if the $nth$ argument of the $jth$ constructor of + the $ith$ type is recursive, and \texttt{Norec} if it is not.}. +\end{description} + +\subsection{The Type Checker} +\label{TypeChecker} + +The third logical module is the type checker. It concentrates two main +tasks concerning the language of constructions. + +On one hand, it contains the type inference and type-checking +functions. The type inference function takes a term +$a$ and a signature $\Gamma$, and yields a term $A$ such that +$\Gamma \vdash a:A$. The type-checking function takes two terms $a$ +and $A$ and a signature $\Gamma$, and determines whether or not +$\Gamma \vdash a:A$. + +On the other hand, this module is in charge of the compilation of +\Coq's abstract syntax trees into the language \texttt{constr} of +constructions. This compilation seeks to eliminate all the ambiguities +contained in \Coq's abstract syntax, restoring the information +necessary to type-check it. It concerns at least the following steps: +\begin{enumerate} +\item Compiling the pattern-matching expressions containing +constructor patterns, wild-cards, etc, into terms that only +use the primitive \textsl{Case} described in Chapter \ref{Cic} +\item Restoring type coercions and synthesizing the implicit arguments +(the one denoted by question marks in +{\Coq} syntax: cf section \ref{Coercions}). +\item Transforming the named bound variables into deBrujin's indexes. +\item Classifying the global names into the different classes of +constants (defined constants, constructors, inductive types, etc). +\end{enumerate} + +\subsection{The Proof Engine} + +The fourth stage of \Coq's implementation is the \textsl{proof engine}: +the interactive machine for constructing proofs. The aim of the proof +engine is to construct a top-down derivation or \textsl{proof tree}, +by the application of \textsl{tactics}. A proof tree has the following +general structure:\\ + +\begin{displaymath} +\frac{\Gamma \vdash ? = t(?_1,\ldots?_n) : G} + {\hspace{3ex}\frac{\displaystyle \Gamma_1 \vdash ?_1 = t_1(\ldots) : G_1} + {\stackrel{\vdots}{\displaystyle {\Gamma_{i_1} \vdash ?_{i_1} + : G_{i_1}}}}(tac_1) + \;\;\;\;\;\;\;\;\; + \frac{\displaystyle \Gamma_n \vdash ?_n = t_n(\ldots) : G_n} + {\displaystyle \stackrel{\vdots}{\displaystyle {\Gamma_{i_m} \vdash ?_{i_m} : + G_{i_m}}}}(tac_n)} (tac) +\end{displaymath} + + +\noindent Each node of the tree is called a \textsl{goal}. A goal +is a record type containing the following three fields: +\begin{enumerate} +\item the conclusion $G$ to be proven; +\item a typing signature $\Gamma$ for the free variables in $G$; +\item if the goal is an internal node of the proof tree, the +definition $t(?_1,\ldots?_n)$ of an \textsl{existential variable} +(i.e. a possible undefined constant) $?$ of type $G$ in terms of the +existential variables of the children sub-goals. If the node is a +leaf, the existential variable maybe still undefined. +\end{enumerate} + +Once all the existential variables have been defined the derivation is +completed, and a construction can be generated from the proof tree, +replacing each of the existential variables by its definition. This +is exactly what happens when one of the commands +\texttt{Qed}, \texttt{Save} or \texttt{Defined} is invoked +(cf. Section \ref{Qed}). The saved theorem becomes a defined constant, +whose body is the proof object generated. + +\paragraph{Important:} Before being added to the +context, the proof object is type-checked, in order to verify that it is +actually an object of the expected type $G$. Hence, the correctness +of the proof actually does not depend on the tactics applied to +generate it or the machinery of the proof engine, but only on the +type-checker. In other words, extending the system with a potentially +bugged new tactic never endangers the consistency of the system. + +\subsubsection{What is a Tactic?} +\label{WhatIsATactic} +%Let us now explain what is a tactic, and how the user can introduce +%new ones. + +From an operational point of view, the current state of the proof +engine is given by the mapping $emap$ from existential variables into +goals, plus a pointer to one of the leaf goals $g$. Such a pointer +indicates where the proof tree will be refined by the application of a +\textsl{tactic}. A tactic is a function from the current state +$(g,emap)$ of the proof engine into a pair $(l,val)$. The first +component of this pair is the list of children sub-goals $g_1,\ldots +g_n$ of $g$ to be yielded by the tactic. The second one is a +\textsl{validation function}. Once the proof trees $\pi_1,\ldots +\pi_n$ for $g_1,\ldots g_n$ have been completed, this validation +function must yield a proof tree $(val\;\pi_1,\ldots \pi_n)$ deriving +$g$. + +Tactics can be classified into \textsl{primitive} ones and +\textsl{defined} ones. Primitive tactics correspond to the five basic +operations of the proof engine: + +\begin{enumerate} +\item Introducing a universally quantified variable into the local +context of the goal. +\item Defining an undefined existential variable +\item Changing the conclusion of the goal for another +--definitionally equal-- term. +\item Changing the type of a variable in the local context for another +definitionally equal term. +\item Erasing a variable from the local context. +\end{enumerate} + +\textsl{Defined} tactics are tactics constructed by combining these +primitive operations. Defined tactics are registered in a hash table, +so that they can be introduced dynamically. In order to define such a +tactic table, it is necessary to fix what a \textsl{possible argument} +of a tactic may be. The type \texttt{tactic\_arg} of the possible +arguments for tactics is a union type including: +\begin{itemize} +\item quoted strings; +\item integers; +\item identifiers; +\item lists of identifiers; +\item plain terms, represented by its abstract syntax tree; +\item well-typed terms, represented by a construction; +\item a substitution for bound variables, like the +substitution in the tactic \\$\texttt{Apply}\;t\;\texttt{with}\;x:=t_1\ldots +x_n:=t_n$, (cf. Section \ref{Apply}); +\item a reduction expression, denoting the reduction strategy to be +followed. +\end{itemize} +Therefore, for each function $tac:a \rightarrow tactic$ implementing a +defined tactic, an associated dynamic tactic $tacargs\_tac: +\texttt{tactic\_arg}\;list \rightarrow tactic$ calling $tac$ must be +written. The aim of the auxiliary function $tacargs\_tac$ is to inject +the arguments of the tactic $tac$ into the type of possible arguments +for a tactic. + +The following function can be used for registering and calling a +defined tactic: + +\begin{description} +\fun{val Tacmach.add\_tactic : \\ \qquad +string -> (tactic\_arg list ->tactic) -> unit} + {\\ Registers a dynamic tactic with the given string as access index.} +\fun{val Tacinterp.vernac\_tactic : string*tactic\_arg list -> tactic} + {Interprets a defined tactic given by its entry in the + tactics table with a particular list of possible arguments.} +\fun{val Tacinterp.vernac\_interp : CoqAst.t -> tactic} + {Interprets a tactic expression formed combining \Coq's tactics and + tacticals, and described by its abstract syntax tree.} +\end{description} + +When programming a new tactic that calls an already defined tactic +$tac$, we have the choice between using the \ocaml{} function +implementing $tac$, or calling the tactic interpreter with the name +and arguments for interpreting $tac$. In the first case, a tactic call +will left the trace of the whole implementation of $tac$ in the proof +tree. In the second, the implementation of $tac$ will be hidden, and +only an invocation of $tac$ will be recalled (cf. the example of +Section \ref{ACompleteExample}. The following combinators can be used +to hide the implementation of a tactic: + +\begin{verbatim} +type 'a hiding_combinator = string -> ('a -> tactic) -> ('a -> tactic) +val Tacmach.hide_atomic_tactic : string -> tactic -> tactic +val Tacmach.hide_constr_tactic : constr hiding_combinator +val Tacmach.hide_constrl_tactic : (constr list) hiding_combinator +val Tacmach.hide_numarg_tactic : int hiding_combinator +val Tacmach.hide_ident_tactic : identifier hiding_combinator +val Tacmach.hide_identl_tactic : identifier hiding_combinator +val Tacmach.hide_string_tactic : string hiding_combinator +val Tacmach.hide_bindl_tactic : substitution hiding_combinator +val Tacmach.hide_cbindl_tactic : + (constr * substitution) hiding_combinator +\end{verbatim} + +These functions first register the tactic by a side effect, and then +yield a function calling the interpreter with the registered name and +the right injection into the type of possible arguments. + +\subsection{Tactics and Tacticals Provided by \Coq} + +The fifth logical module is the library of tacticals and basic tactics +provided by \Coq. This library is distributed into the directories +\texttt{tactics} and \texttt{src/tactics}. The former contains those +basic tactics that make use of the types contained in the basic state +of \Coq. For example, inversion or rewriting tactics are in the +directory \texttt{tactics}, since they make use of the propositional +equality type. Those tactics which are independent from the context +--like for example \texttt{Cut}, \texttt{Intros}, etc-- are defined in +the directory \texttt{src/tactics}. This latter directory also +contains some useful tools for programming new tactics, referred in +Section \ref{SomeUsefulToolsforWrittingTactics}. + +In practice, it is very unusual that the list of sub-goals and the +validation function of the tactic must be explicitly constructed by +the user. In most of the cases, the implementation of a new tactic +consists in supplying the appropriate arguments to the basic tactics +and tacticals. + +\subsubsection{Basic Tactics} + +The file \texttt{Tactics} contain the implementation of the basic +tactics provided by \Coq. The following tactics are some of the most +used ones: + +\begin{verbatim} +val Tactics.intro : tactic +val Tactics.assumption : tactic +val Tactics.clear : identifier list -> tactic +val Tactics.apply : constr -> constr substitution -> tactic +val Tactics.one_constructor : int -> constr substitution -> tactic +val Tactics.simplest_elim : constr -> tactic +val Tactics.elimType : constr -> tactic +val Tactics.simplest_case : constr -> tactic +val Tactics.caseType : constr -> tactic +val Tactics.cut : constr -> tactic +val Tactics.reduce : redexpr -> tactic +val Tactics.exact : constr -> tactic +val Auto.auto : int option -> tactic +val Auto.trivial : tactic +\end{verbatim} + +The functions hiding the implementation of these tactics are defined +in the module \texttt{Hiddentac}. Their names are prefixed by ``h\_''. + +\subsubsection{Tacticals} +\label{OcamlTacticals} + +The following tacticals can be used to combine already existing +tactics: + +\begin{description} +\fun{val Tacticals.tclIDTAC : tactic} + {The identity tactic: it leaves the goal as it is.} + +\fun{val Tacticals.tclORELSE : tactic -> tactic -> tactic} + {Tries the first tactic and in case of failure applies the second one.} + +\fun{val Tacticals.tclTHEN : tactic -> tactic -> tactic} + {Applies the first tactic and then the second one to each generated subgoal.} + +\fun{val Tacticals.tclTHENS : tactic -> tactic list -> tactic} + {Applies a tactic, and then applies each tactic of the tactic list to the + corresponding generated subgoal.} + +\fun{val Tacticals.tclTHENL : tactic -> tactic -> tactic} + {Applies the first tactic, and then applies the second one to the last + generated subgoal.} + +\fun{val Tacticals.tclREPEAT : tactic -> tactic} + {If the given tactic succeeds in producing a subgoal, then it + is recursively applied to each generated subgoal, + and so on until it fails. } + +\fun{val Tacticals.tclFIRST : tactic list -> tactic} + {Tries the tactics of the given list one by one, until one of them + succeeds.} + +\fun{val Tacticals.tclTRY : tactic -> tactic} + {Tries the given tactic and in case of failure applies the {\tt + tclIDTAC} tactical to the original goal.} + +\fun{val Tacticals.tclDO : int -> tactic -> tactic} + {Applies the tactic a given number of times.} + +\fun{val Tacticals.tclFAIL : tactic} + {The always failing tactic: it raises a {\tt UserError} exception.} + +\fun{val Tacticals.tclPROGRESS : tactic -> tactic} + {Applies the given tactic to the current goal and fails if the + tactic leaves the goal unchanged} + +\fun{val Tacticals.tclNTH\_HYP : int -> (constr -> tactic) -> tactic} + {Applies a tactic to the nth hypothesis of the local context. + The last hypothesis introduced correspond to the integer 1.} + +\fun{val Tacticals.tclLAST\_HYP : (constr -> tactic) -> tactic} + {Applies a tactic to the last hypothesis introduced.} + +\fun{val Tacticals.tclCOMPLETE : tactic -> tactic} + {Applies a tactic and fails if the tactic did not solve completely the + goal} + +\fun{val Tacticals.tclMAP : ('a -> tactic) -> 'a list -> tactic} + {Applied to the function \texttt{f} and the list \texttt{[x\_1; + ... ; x\_n]}, this tactical applies the tactic + \texttt{tclTHEN (f x1) (tclTHEN (f x2) ... ))))}} + +\fun{val Tacicals.tclIF : (goal sigma -> bool) -> tactic -> tactic -> tactic} + {If the condition holds, apply the first tactic; otherwise, + apply the second one} + +\end{description} + + +\subsection{The Vernacular Interpreter} + +The sixth logical module of the implementation corresponds to the +interpreter of the vernacular phrases of \Coq. These phrases may be +expressions from the \gallina{} language (definitions), general +directives (setting commands) or tactics to be applied by the proof +engine. + +\subsection{The Parser and the Pretty-Printer} +\label{PrettyPrinter} + +The last logical module is the parser and pretty printer of \Coq, +which is the interface between the vernacular interpreter and the +user. They translate the chains of characters entered at the input +into abstract syntax trees, and vice versa. Abstract syntax trees are +represented by labeled n-ary trees, and its type is called +\texttt{CoqAst.t}. For instance, the abstract syntax tree associated +to the term $[x:A]x$ is: + +\begin{displaymath} +\texttt{Node} + ((0,6), "LAMBDA", + [\texttt{Nvar}~((3, 4),"A");~\texttt{Slam}~((0,6),~Some~"x",~\texttt{Nvar}~((5,6),"x"))]) +\end{displaymath} + +The numbers correspond to \textsl{locations}, used to point to some +input line and character positions in the error messages. As it was +already explained in Section \ref{TypeChecker}, this term is then +translated into a construction term in order to be typed. + +The parser of \Coq\ is implemented using \camlpppp. The lexer and the data +used by \camlpppp\ to generate the parser lay in the directory +\texttt{src/parsing}. This directory also contains \Coq's +pretty-printer. The printing rules lay in the directory +\texttt{src/syntax}. The different entries of the grammar are +described in the module \texttt{Pcoq.Entry}. Let us present here two +important functions of this logical module: + +\begin{description} +\fun{val Pcoq.parse\_string : 'a Grammar.Entry.e -> string -> 'a} + {Parses a given string, trying to recognize a phrase + corresponding to some entry in the grammar. If it succeeds, + it yields a value associated to the grammar entry. For example, + applied to the entry \texttt{Pcoq.Command.command}, this function + parses a term of \Coq's language, and yields a value of type + \texttt{CoqAst.t}. When applied to the entry + \texttt{Pcoq.Vernac.vernac}, it parses a vernacular command and + returns the corresponding Ast.} +\fun{val gentermpr : \\ \qquad +path\_kind -> constr assumptions -> constr -> std\_ppcmds} + {\\ Pretty-prints a well-typed term of certain kind (cf. Section + \ref{SectionPaths}) under its context of typing assumption.} +\fun{val gentacpr : CoqAst.t -> std\_ppcmds} + {Pretty-prints a given abstract syntax tree representing a tactic + expression.} +\end{description} + +\subsection{The General Library} + +In addition to the ones laying in the standard library of \ocaml{}, +several useful modules about lists, arrays, sets, mappings, balanced +trees, and other frequently used data structures can be found in the +directory \texttt{lib}. Before writing a new one, check if it is not +already there! + +\subsubsection{The module \texttt{Std}} +This module in the directory \texttt{src/lib/util} is opened by almost +all modules of \Coq{}. Among other things, it contains a definition of +the different kinds of errors used in \Coq{} : + +\begin{description} +\fun{exception UserError of string * std\_ppcmds} + {This is the class of ``users exceptions''. Such errors arise when + the user attempts to do something illegal, for example \texttt{Intro} + when the current goal conclusion is not a product.} + +\fun{val Std.error : string -> 'a} + {For simple error messages} +\fun{val Std.errorlabstrm : string -> std\_ppcmds -> 'a} + {See section \ref{PrettyPrinter} : this can be used if the user + want to display a term or build a complex error message} + +\fun{exception Anomaly of string * std\_ppcmds} + {This for reporting bugs or things that should not + happen. The tacticals \texttt{tclTRY} and + \texttt{tclTRY} described in section \ref{OcamlTacticals} catch the + exceptions of type \texttt{UserError}, but they don't catch the + anomalies. So, in your code, don't raise any anomaly, unless you + know what you are doing. We also recommend to avoid constructs + such as \texttt{try ... with \_ -> ...} : such constructs can trap + an anomaly and make the debugging process harder.} + +\fun{val Std.anomaly : string -> 'a}{} +\fun{val Std.anomalylabstrm : string -> std\_ppcmds -> 'a}{} +\end{description} + +\section{The tactic writer mini-HOWTO} + +\subsection{How to add a vernacular command} + +The command to register a vernacular command can be found +in module \texttt{Vernacinterp}: + +\begin{verbatim} +val vinterp_add : string * (vernac_arg list -> unit -> unit) -> unit;; +\end{verbatim} + +The first argument is the name, the second argument is a function that +parses the arguments and returns a function of type +\texttt{unit}$\rightarrow$\texttt{unit} that do the job. + +In this section we will show how to add a vernacular command +\texttt{CheckCheck} that print a type of a term and the type of its +type. + +File \texttt{dcheck.ml}: + +\begin{verbatim} +open Vernacinterp;; +open Trad;; +let _ = + vinterp_add + ("DblCheck", + function [VARG_COMMAND com] -> + (fun () -> + let evmap = Evd.mt_evd () + and sign = Termenv.initial_sign () in + let {vAL=c;tYP=t;kIND=k} = + fconstruct_with_univ evmap sign com in + Pp.mSGNL [< Printer.prterm c; 'sTR ":"; + Printer.prterm t; 'sTR ":"; + Printer.prterm k >] ) + | _ -> bad_vernac_args "DblCheck") +;; +\end{verbatim} + +Like for a new tactic, a new syntax entry must be created. + +File \texttt{DCheck.v}: + +\begin{verbatim} +Declare ML Module "dcheck.ml". + +Grammar vernac vernac := + dblcheck [ "CheckCheck" comarg($c) ] -> [(DblCheck $c)]. +\end{verbatim} + +We are now able to test our new command: + +\begin{verbatim} +Coq < Require DCheck. +Coq < CheckCheck O. +O:nat:Set +\end{verbatim} + +Most Coq vernacular commands are registered in the module + \verb+src/env/vernacentries.ml+. One can see more examples here. + +\subsection{How to keep a hashtable synchronous with the reset mechanism} + +This is far more tricky. Some vernacular commands modify some +sort of state (for example by adding something in a hashtable). One +wants that \texttt{Reset} has the expected behavior with this +commands. + +\Coq{} provides a general mechanism to do that. \Coq{} environments +contains objects of three kinds: CCI, FW and OBJ. CCI and FW are for +constants of the calculus. OBJ is a dynamically extensible datatype +that contains sections, tactic definitions, hints for auto, and so +on. + +The simplest example of use of such a mechanism is in file +\verb+src/proofs/macros.ml+ (which implements the \texttt{Tactic + Definition} command). Tactic macros are stored in the imperative +hashtable \texttt{mactab}. There are two functions freeze and unfreeze +to make a copy of the table and to restore the state of table from the +copy. Then this table is declared using \texttt{Library.declare\_summary}. + +What does \Coq{} with that ? \Coq{} defines synchronization points. +At each synchronisation point, the declared tables are frozen (that +is, a copy of this tables is stored). + +When \texttt{Reset }$i$ is called, \Coq{} goes back to the first +synchronisation point that is above $i$ and ``replays'' all objects +between that point +and $i$. It will re-declare constants, re-open section, etc. + +So we need to declare a new type of objects, TACTIC-MACRO-DATA. To +``replay'' on object of that type is to add the corresponding tactic +macro to \texttt{mactab} + +So, now, we can say that \texttt{mactab} is synchronous with the Reset +mechanism$^{\mathrm{TM}}$. + +Notice that this works for hash tables but also for a single integer +(the Undo stack size, modified by the \texttt{Set Undo} command, for +example). + +\subsection{The right way to access to Coq constants from your ML code} + +With their long names, Coq constants are stored using: + +\begin{itemize} +\item a section path +\item an identifier +\end{itemize} + +The identifier is exactly the identifier that is used in \Coq{} to +denote the constant; the section path can be known using the +\texttt{Locate} command: + +\begin{coq_example} + Locate S. + Locate nat. + Locate eq. +\end{coq_example} + +Now it is easy to get a constant by its name and section path: + + +\begin{verbatim} +let constant sp id = + Machops.global_reference (Names.gLOB (Termenv.initial_sign ())) + (Names.path_of_string sp) (Names.id_of_string id);; +\end{verbatim} + + +The only issue is that if one cannot put: + + +\begin{verbatim} +let coq_S = constant "#Datatypes#nat.cci" "S";; +\end{verbatim} + + +in his tactic's code. That is because this sentence is evaluated +\emph{before} the module \texttt{Datatypes} is loaded. The solution is +to use the lazy evaluation of \ocaml{}: + + +\begin{verbatim} +let coq_S = lazy (constant "#Datatypes#nat.cci" "S");; + +... (Lazy.force coq_S) ... +\end{verbatim} + + +Be sure to call always Lazy.force behind a closure -- i.e. inside a +function body or behind the \texttt{lazy} keyword. + +One can see examples of that technique in the source code of \Coq{}, +for example +\verb+tactics/contrib/polynom/ring.ml+ or +\verb+tactics/contrib/polynom/coq_omega.ml+. + +\section{Some Useful Tools for Writing Tactics} +\label{SomeUsefulToolsforWrittingTactics} +When the implementation of a tactic is not a straightforward +combination of tactics and tacticals, the module \texttt{Tacmach} +provides several useful functions for handling goals, calling the +type-checker, parsing terms, etc. This module is intended to be +the interface of the proof engine for the user. + +\begin{description} +\fun{val Tacmach.pf\_hyps : goal sigma -> constr signature} + {Projects the local typing context $\Gamma$ from a given goal $\Gamma\vdash ?:G$.} +\fun{val pf\_concl : goal sigma -> constr} + {Projects the conclusion $G$ from a given goal $\Gamma\vdash ?:G$.} +\fun{val Tacmach.pf\_nth\_hyp : goal sigma -> int -> identifier * + constr} + {Projects the $ith$ typing constraint $x_i:A_i$ from the local + context of the given goal.} +\fun{val Tacmach.pf\_fexecute : goal sigma -> constr -> judgement} + {Given a goal whose local context is $\Gamma$ and a term $a$, this + function infers a type $A$ and a kind $K$ such that the judgement + $a:A:K$ is valid under $\Gamma$, or raises an exception if there + is no such judgement. A judgement is just a record type containing + the three terms $a$, $A$ and $K$.} +\fun{val Tacmach.pf\_infexecute : \\ + \qquad +goal sigma -> constr -> judgement * information} + {\\ In addition to the typing judgement, this function also extracts + the $F_{\omega}$ program underlying the term.} +\fun{val Tacmach.pf\_type\_of : goal sigma -> constr -> constr} + {Infers a term $A$ such that $\Gamma\vdash a:A$ for a given term + $a$, where $\Gamma$ is the local typing context of the goal.} +\fun{val Tacmach.pf\_check\_type : goal sigma -> constr -> constr -> bool} + {This function yields a type $A$ if the two given terms $a$ and $A$ verify $\Gamma\vdash + a:A$ in the local typing context $\Gamma$ of the goal. Otherwise, + it raises an exception.} +\fun{val Tacmach.pf\_constr\_of\_com : goal sigma -> CoqAst.t -> constr} + {Transforms an abstract syntax tree into a well-typed term of the + language of constructions. Raises an exception if the term cannot + be typed.} +\fun{val Tacmach.pf\_constr\_of\_com\_sort : goal sigma -> CoqAst.t -> constr} + {Transforms an abstract syntax tree representing a type into + a well-typed term of the language of constructions. Raises an + exception if the term cannot be typed.} +\fun{val Tacmach.pf\_parse\_const : goal sigma -> string -> constr} + {Constructs the constant whose name is the given string.} +\fun{val +Tacmach.pf\_reduction\_of\_redexp : \\ + \qquad goal sigma -> red\_expr -> constr -> constr} + {\\ Applies a certain kind of reduction function, specified by an + element of the type red\_expr.} +\fun{val Tacmach.pf\_conv\_x : goal sigma -> constr -> constr -> bool} + {Test whether two given terms are definitionally equal.} +\end{description} + +\subsection{Patterns} +\label{Patterns} + +The \ocaml{} file \texttt{Pattern} provides a quick way for describing a +term pattern and performing second-order, binding-preserving, matching +on it. Patterns are described using an extension of \Coq's concrete +syntax, where the second-order meta-variables of the pattern are +denoted by indexed question marks. + +Patterns may depend on constants, and therefore only to make have +sense when certain theories have been loaded. For this reason, they +are stored with a \textsl{module-marker}, telling us which modules +have to be open in order to use the pattern. The following functions +can be used to store and retrieve patterns form the pattern table: + +\begin{description} +\fun{val Pattern.make\_module\_marker : string list -> module\_mark} + {Constructs a module marker from a list of module names.} +\fun{val Pattern.put\_pat : module\_mark -> string -> marked\_term} + {Constructs a pattern from a parseable string containing holes + and a module marker.} +\fun{val Pattern.somatches : constr -> marked\_term-> bool} + {Tests if a term matches a pattern.} +\fun{val dest\_somatch : constr -> marked\_term -> constr list} + {If the term matches the pattern, yields the list of sub-terms + matching the occurrences of the pattern variables (ordered from + left to right). Raises a \texttt{UserError} exception if the term + does not match the pattern.} +\fun{val Pattern.soinstance : marked\_term -> constr list -> constr} + {Substitutes each hole in the pattern + by the corresponding term of the given the list.} +\end{description} + +\paragraph{Warning:} Sometimes, a \Coq\ term may have invisible +sub-terms that the matching functions are nevertheless sensible to. +For example, the \Coq\ term $(?_1,?_2)$ is actually a shorthand for +the expression $(\texttt{pair}\;?\;?\;?_1\;?_2)$. +Hence, matching this term pattern +with the term $(\texttt{true},\texttt{O})$ actually yields the list +$[?;?;\texttt{true};\texttt{O}]$ as result (and \textbf{not} +$[\texttt{true};\texttt{O}]$, as could be expected). + +\subsection{Patterns on Inductive Definitions} + +The module \texttt{Pattern} also includes some functions for testing +if the definition of an inductive type satisfies certain +properties. Such functions may be used to perform pattern matching +independently from the name given to the inductive type and the +universe it inhabits. They yield the value $(\texttt{Some}\;r::l)$ if +the input term reduces into an application of an inductive type $r$ to +a list of terms $l$, and the definition of $r$ satisfies certain +conditions. Otherwise, they yield the value \texttt{None}. + +\begin{description} +\fun{val Pattern.match\_with\_non\_recursive\_type : constr list option} + {Tests if the inductive type $r$ has no recursive constructors} +\fun{val Pattern.match\_with\_disjunction : constr list option} + {Tests if the inductive type $r$ is a non-recursive type + such that all its constructors have a single argument.} +\fun{val Pattern.match\_with\_conjunction : constr list option} + {Tests if the inductive type $r$ is a non-recursive type + with a unique constructor.} +\fun{val Pattern.match\_with\_empty\_type : constr list option} + {Tests if the inductive type $r$ has no constructors at all} +\fun{val Pattern.match\_with\_equation : constr list option} + {Tests if the inductive type $r$ has a single constructor + expressing the property of reflexivity for some type. For + example, the types $a=b$, $A\mbox{==}B$ and $A\mbox{===}B$ satisfy + this predicate.} +\end{description} + +\subsection{Elimination Tacticals} + +It is frequently the case that the subgoals generated by an +elimination can all be solved in a similar way, possibly parametrized +on some information about each case, like for example: +\begin{itemize} +\item the inductive type of the object being eliminated; +\item its arguments (if it is an inductive predicate); +\item the branch number; +\item the predicate to be proven; +\item the number of assumptions to be introduced by the case +\item the signature of the branch, i.e., for each argument of +the branch whether it is recursive or not. +\end{itemize} + +The following tacticals can be useful to deal with such situations. +They + +\begin{description} +\fun{val Elim.simple\_elimination\_then : \\ \qquad +(branch\_args -> tactic) -> constr -> tactic} + {\\ Performs the default elimination on the last argument, and then + tries to solve the generated subgoals using a given parametrized + tactic. The type branch\_args is a record type containing all + information mentioned above.} +\fun{val Elim.simple\_case\_then : \\ \qquad +(branch\_args -> tactic) -> constr -> tactic} + {\\ Similarly, but it performs case analysis instead of induction.} +\end{description} + +\section{A Complete Example} +\label{ACompleteExample} + +In order to illustrate the implementation of a new tactic, let us come +back to the problem of deciding the equality of two elements of an +inductive type. + +\subsection{Preliminaries} + +Let us call \texttt{newtactic} the directory that will contain the +implementation of the new tactic. In this directory will lay two +files: a file \texttt{eqdecide.ml}, containing the \ocaml{} sources that +implements the tactic, and a \Coq\ file \texttt{Eqdecide.v}, containing +its associated grammar rules and the commands to generate a module +that can be loaded dynamically from \Coq's toplevel. + +To compile our project, we will create a \texttt{Makefile} with the +command \texttt{do\_Makefile} (see section \ref{Makefile}) : + +\begin{quotation} + \texttt{do\_Makefile eqdecide.ml EqDecide.v > Makefile}\\ + \texttt{touch .depend}\\ + \texttt{make depend} +\end{quotation} + +We must have kept the sources of \Coq{} somewhere and to set an +environment variable \texttt{COQTOP} that points to that directory. + +\subsection{Implementing the Tactic} + +The file \texttt{eqdecide.ml} contains the implementation of the +tactic in \ocaml{}. Let us recall the main steps of the proof strategy +for deciding the proposition $(x,y:R)\{x=y\}+\{\neg x=y\}$ on the +inductive type $R$: +\begin{enumerate} +\item Eliminate $x$ and then $y$. +\item Try discrimination to solve those goals where $x$ and $y$ has +been introduced by different constructors. +\item If $x$ and $y$ have been introduced by the same constructor, + then analyze one by one the corresponding pairs of arguments. + If they are equal, rewrite one into the other. If they are + not, derive a contradiction from the invectiveness of the + constructor. +\item Once all the arguments have been rewritten, solve the left half +of the goal by reflexivity. +\end{enumerate} + +In the sequel we implement these steps one by one. We start opening +the modules necessary for the implementation of the tactic: + +\begin{verbatim} +open Names +open Term +open Tactics +open Tacticals +open Hiddentac +open Equality +open Auto +open Pattern +open Names +open Termenv +open Std +open Proof_trees +open Tacmach +\end{verbatim} + +The first step of the procedure can be straightforwardly implemented as +follows: + +\begin{verbatim} +let clear_last = (tclLAST_HYP (fun c -> (clear_one (destVar c))));; +\end{verbatim} + +\begin{verbatim} +let mkBranches = + (tclTHEN intro + (tclTHEN (tclLAST_HYP h_simplest_elim) + (tclTHEN clear_last + (tclTHEN intros + (tclTHEN (tclLAST_HYP h_simplest_case) + (tclTHEN clear_last + intros))))));; +\end{verbatim} + +Notice the use of the tactical \texttt{tclLAST\_HYP}, which avoids to +give a (potentially clashing) name to the quantified variables of the +goal when they are introduced. + +The second step of the procedure is implemented by the following +tactic: + +\begin{verbatim} +let solveRightBranch = (tclTHEN simplest_right discrConcl);; +\end{verbatim} + +In order to illustrate how the implementation of a tactic can be +hidden, let us do it with the tactic above: + +\begin{verbatim} +let h_solveRightBranch = + hide_atomic_tactic "solveRightBranch" solveRightBranch +;; +\end{verbatim} + +As it was already mentioned in Section \ref{WhatIsATactic}, the +combinator \texttt{hide\_atomic\_tactic} first registers the tactic +\texttt{solveRightBranch} in the table, and returns a tactic which +calls the interpreter with the used to register it. Hence, when the +tactical \texttt{Info} is used, our tactic will just inform that +\texttt{solveRightBranch} was applied, omitting all the details +corresponding to \texttt{simplest\_right} and \texttt{discrConcl}. + + + +The third step requires some auxiliary functions for constructing the +type $\{c_1=c_2\}+\{\neg c_1=c_2\}$ for a given inductive type $R$ and +two constructions $c_1$ and $c_2$, and for generalizing this type over +$c_1$ and $c_2$: + +\begin{verbatim} +let mmk = make_module_marker ["#Logic.obj";"#Specif.obj"];; +let eqpat = put_pat mmk "eq";; +let sumboolpat = put_pat mmk "sumbool";; +let notpat = put_pat mmk "not";; +let eq = get_pat eqpat;; +let sumbool = get_pat sumboolpat;; +let not = get_pat notpat;; + +let mkDecideEqGoal rectype c1 c2 g = + let equality = mkAppL [eq;rectype;c1;c2] in + let disequality = mkAppL [not;equality] + in mkAppL [sumbool;equality;disequality] +;; +let mkGenDecideEqGoal rectype g = + let hypnames = ids_of_sign (pf_hyps g) in + let xname = next_ident_away (id_of_string "x") hypnames + and yname = next_ident_away (id_of_string "y") hypnames + in (mkNamedProd xname rectype + (mkNamedProd yname rectype + (mkDecideEqGoal rectype (mkVar xname) (mkVar yname) g))) +;; +\end{verbatim} + +The tactic will depend on the \Coq modules \texttt{Logic} and +\texttt{Specif}, since we use the constants corresponding to +propositional equality (\texttt{eq}), computational disjunction +(\texttt{sumbool}), and logical negation (\texttt{not}), defined in +that modules. This is specified creating the module maker +\texttt{mmk} (cf. Section \ref{Patterns}). + +The third step of the procedure can be divided into three sub-steps. +Assume that both $x$ and $y$ have been introduced by the same +constructor. For each corresponding pair of arguments of that +constructor, we have to consider whether they are equal or not. If +they are equal, the following tactic is applied to rewrite one into +the other: + +\begin{verbatim} +let eqCase tac = + (tclTHEN intro + (tclTHEN (tclLAST_HYP h_rewriteLR) + (tclTHEN clear_last + tac))) +;; +\end{verbatim} + + +If they are not equal, then the goal is contraposed and a +contradiction is reached form the invectiveness of the constructor: + +\begin{verbatim} +let diseqCase = + let diseq = (id_of_string "diseq") in + let absurd = (id_of_string "absurd") + in (tclTHEN (intro_using diseq) + (tclTHEN h_simplest_right + (tclTHEN red_in_concl + (tclTHEN (intro_using absurd) + (tclTHEN (h_simplest_apply (mkVar diseq)) + (tclTHEN (h_injHyp absurd) + trivial )))))) +;; +\end{verbatim} + +In the tactic above we have chosen to name the hypotheses because +they have to be applied later on. This introduces a potential risk +of name clashing if the context already contains other hypotheses +also named ``diseq'' or ``absurd''. + +We are now ready to implement the tactic \textsl{SolveArg}. Given the +two arguments $a_1$ and $a_2$ of the constructor, this tactic cuts the +goal with the proposition $\{a_1=a_2\}+\{\neg a_1=a_2\}$, and then +applies the tactics above to each of the generated cases. If the +disjunction cannot be solved automatically, it remains as a sub-goal +to be proven. + +\begin{verbatim} +let solveArg a1 a2 tac g = + let rectype = pf_type_of g a1 in + let decide = mkDecideEqGoal rectype a1 a2 g + in (tclTHENS (h_elimType decide) + [(eqCase tac);diseqCase;default_auto]) g +;; +\end{verbatim} + +The following tactic implements the third and fourth steps of the +proof procedure: + +\begin{verbatim} +let conclpatt = put_pat mmk "{<?1>?2=?3}+{?4}" +;; +let solveLeftBranch rectype g = + let (_::(lhs::(rhs::_))) = + try (dest_somatch (pf_concl g) conclpatt) + with UserError ("somatch",_)-> error "Unexpected conclusion!" in + let nparams = mind_nparams rectype in + let getargs l = snd (chop_list nparams (snd (decomp_app l))) in + let rargs = getargs rhs + and largs = getargs lhs + in List.fold_right2 + solveArg largs rargs (tclTHEN h_simplest_left h_reflexivity) g +;; +\end{verbatim} + +Notice the use of a pattern to decompose the goal and obtain the +inductive type and the left and right hand sides of the equality. A +certain number of arguments correspond to the general parameters of +the type, and must be skipped over. Once the corresponding list of +arguments \texttt{rargs} and \texttt{largs} have been obtained, the +tactic \texttt{solveArg} is iterated on them, leaving a disjunction +whose left half can be solved by reflexivity. + +The following tactic joints together the three steps of the +proof procedure: + +\begin{verbatim} +let initialpatt = put_pat mmk "(x,y:?1){<?1>x=y}+{~(<?1>x=y)}" +;; +let decideGralEquality g = + let (typ::_) = try (dest_somatch (pf_concl g) initialpatt) + with UserError ("somatch",_) -> + error "The goal does not have the expected form" in + let headtyp = hd_app (pf_compute g typ) in + let rectype = match (kind_of_term headtyp) with + IsMutInd _ -> headtyp + | _ -> error ("This decision procedure only" + " works for inductive objects") + in (tclTHEN mkBranches + (tclORELSE h_solveRightBranch (solveLeftBranch rectype))) g +;; +;; +\end{verbatim} + +The tactic above can be specialized in two different ways: either to +decide a particular instance $\{c_1=c_2\}+\{\neg c_1=c_2\}$ of the +universal quantification; or to eliminate this property and obtain two +subgoals containing the hypotheses $c_1=c_2$ and $\neg c_1=c_2$ +respectively. + +\begin{verbatim} +let decideGralEquality = + (tclTHEN mkBranches (tclORELSE h_solveRightBranch solveLeftBranch)) +;; +let decideEquality c1 c2 g = + let rectype = pf_type_of g c1 in + let decide = mkGenDecideEqGoal rectype g + in (tclTHENS (cut decide) [default_auto;decideGralEquality]) g +;; +let compare c1 c2 g = + let rectype = pf_type_of g c1 in + let decide = mkDecideEqGoal rectype c1 c2 g + in (tclTHENS (cut decide) + [(tclTHEN intro + (tclTHEN (tclLAST_HYP simplest_case) + clear_last)); + decideEquality c1 c2]) g +;; +\end{verbatim} + +Next, for each of the tactics that will have an entry in the grammar +we construct the associated dynamic one to be registered in the table +of tactics. This function can be used to overload a tactic name with +several similar tactics. For example, the tactic proving the general +decidability property and the one proving a particular instance for +two terms can be grouped together with the following convention: if +the user provides two terms as arguments, then the specialized tactic +is used; if no argument is provided then the general tactic is invoked. + +\begin{verbatim} +let dyn_decideEquality args g = + match args with + [(COMMAND com1);(COMMAND com2)] -> + let c1 = pf_constr_of_com g com1 + and c2 = pf_constr_of_com g com2 + in decideEquality c1 c2 g + | [] -> decideGralEquality g + | _ -> error "Invalid arguments for dynamic tactic" +;; +add_tactic "DecideEquality" dyn_decideEquality +;; + +let dyn_compare args g = + match args with + [(COMMAND com1);(COMMAND com2)] -> + let c1 = pf_constr_of_com g com1 + and c2 = pf_constr_of_com g com2 + in compare c1 c2 g + | _ -> error "Invalid arguments for dynamic tactic" +;; +add_tactic "Compare" tacargs_compare +;; +\end{verbatim} + +This completes the implementation of the tactic. We turn now to the +\Coq file \texttt{Eqdecide.v}. + + +\subsection{The Grammar Rules} + +Associated to the implementation of the tactic there is a \Coq\ file +containing the grammar and pretty-printing rules for the new tactic, +and the commands to generate an object module that can be then loaded +dynamically during a \Coq\ session. In order to generate an ML module, +the \Coq\ file must contain a +\texttt{Declare ML module} command for all the \ocaml{} files concerning +the implementation of the tactic --in our case there is only one file, +the file \texttt{eqdecide.ml}: + +\begin{verbatim} +Declare ML Module "eqdecide". +\end{verbatim} + +The following grammar and pretty-printing rules are +self-explanatory. We refer the reader to the Section \ref{Grammar} for +the details: + +\begin{verbatim} +Grammar tactic simple_tactic := + EqDecideRuleG1 + [ "Decide" "Equality" comarg($com1) comarg($com2)] -> + [(DecideEquality $com1 $com2)] +| EqDecideRuleG2 + [ "Decide" "Equality" ] -> + [(DecideEquality)] +| CompareRule + [ "Compare" comarg($com1) comarg($com2)] -> + [(Compare $com1 $com2)]. + +Syntax tactic level 0: + EqDecideRulePP1 + [(DecideEquality)] -> + ["Decide" "Equality"] +| EqDecideRulePP2 + [(DecideEquality $com1 $com2)] -> + ["Decide" "Equality" $com1 $com2] +| ComparePP + [(Compare $com1 $com2)] -> + ["Compare" $com1 $com2]. +\end{verbatim} + + +\paragraph{Important:} The names used to label the abstract syntax tree +in the grammar rules ---in this case ``DecideEquality'' and +``Compare''--- must be the same as the name used to register the +tactic in the tactics table. This is what makes the links between the +input entered by the user and the tactic executed by the interpreter. + +\subsection{Loading the Tactic} + +Once the module \texttt{EqDecide.v} has been compiled, the tactic can +be dynamically loaded using the \texttt{Require} command. + +\begin{coq_example} +Require EqDecide. +Goal (x,y:nat){x=y}+{~x=y}. +Decide Equality. +\end{coq_example} + +The implementation of the tactic can be accessed through the +tactical \texttt{Info}: +\begin{coq_example} +Undo. +Info Decide Equality. +\end{coq_example} +\begin{coq_eval} +Abort. +\end{coq_eval} + +Remark that the task performed by the tactic \texttt{solveRightBranch} +is not displayed, since we have chosen to hide its implementation. + +\section{Testing and Debugging your Tactic} +\label{test-and-debug} + +When your tactic does not behave as expected, it is possible to trace +it dynamically from \Coq. In order to do this, you have first to leave +the toplevel of \Coq, and come back to the \ocaml{} interpreter. This can +be done using the command \texttt{Drop} (cf. Section \ref{Drop}). Once +in the \ocaml{} toplevel, load the file \texttt{tactics/include.ml}. +This file installs several pretty printers for proof trees, goals, +terms, abstract syntax trees, names, etc. It also contains the +function \texttt{go:unit -> unit} that enables to go back to \Coq's +toplevel. + +The modules \texttt{Tacmach} and \texttt{Pfedit} contain some basic +functions for extracting information from the state of the proof +engine. Such functions can be used to debug your tactic if +necessary. Let us mention here some of them: + +\begin{description} +\fun{val get\_pftreestate : unit -> pftreestate} + {Projects the current state of the proof engine.} +\fun{val proof\_of\_pftreestate : pftreestate -> proof} + {Projects the current state of the proof tree. A pretty-printer + displays it in a readable form. } +\fun{val top\_goal\_of\_pftreestate : pftreestate -> goal sigma} + {Projects the goal and the existential variables mapping from + the current state of the proof engine.} +\fun{val nth\_goal\_of\_pftreestate : int -> pftreestate -> goal sigma} + {Projects the goal and mapping corresponding to the $nth$ subgoal + that remains to be proven} +\fun{val traverse : int -> pftreestate -> pftreestate} + {Yields the children of the node that the current state of the + proof engine points to.} +\fun{val solve\_nth\_pftreestate : \\ \qquad +int -> tactic -> pftreestate -> pftreestate} + {\\ Provides the new state of the proof engine obtained applying + a given tactic to some unproven sub-goal.} +\end{description} + +Finally, the traditional \ocaml{} debugging tools like the directives +\texttt{trace} and \texttt{untrace} can be used to follow the +execution of your functions. Frequently, a better solution is to use +the \ocaml{} debugger, see Chapter \ref{Utilities}. + + +%\end{document} diff --git a/doc/RefMan-uti.tex b/doc/RefMan-uti.tex new file mode 100755 index 000000000..cd266d4cf --- /dev/null +++ b/doc/RefMan-uti.tex @@ -0,0 +1,292 @@ +\chapter{Utilities}\label{Utilities} + +The distribution provides utilities to simplify some tedious works +beside proof development, tactics writing or documentation. + +\section{Building a toplevel extended with user tactics} +\label{Coqmktop}\index{Coqmktop@{\tt coqmktop}} + +The native-code version of \Coq\ cannot dynamically load user tactics +using Objective Caml code. It is possible to build a toplevel of \Coq, +with Objective Caml code statically linked, with the tool {\tt + coqmktop}. + +For example, one can build a native-code \Coq\ toplevel extended with a tactic +which source is in {\tt tactic.ml} with the command +\begin{verbatim} + % coqmktop -opt -o mytop.out tactic.cmx +\end{verbatim} +where {\tt tactic.ml} has been compiled with the native-code +compiler {\tt ocamlopt}. This command generates an image of \Coq\ +called {\tt mytop.out}. One can run this new toplevel with the command +{\tt coqtop -image mytop.out}. + +A basic example is the native-code version of \Coq\ ({\tt coqtop + -opt}), which can be generated by {\tt coqmktop -opt -o coqopt.out}. + +See the man page of {\tt coqmktop} for more details and options. + + +\paragraph{Application: how to use the Objective Caml debugger with Coq.} +\index{Debugger} + +One useful application of \texttt{coqmktop} is to build a \Coq\ toplevel in +order to debug your tactics with the Objective Caml debugger. +You need to have configured and compiled \Coq\ for debugging +(see the file \texttt{INSTALL} included in the distribution). +Then, you must compile the Caml modules of your tactic with the +option \texttt{-g} (with the bytecode compiler) and build a stand-alone +bytecode toplevel with the following command: + +\begin{quotation} +\texttt{\% coqmktop -g -o coq-debug}~\emph{<your \texttt{.cmo} files>} +\end{quotation} + + +To launch the \ocaml debugger with the image you need to execute it in +an environment which correctly sets the \texttt{COQLIB} variable. +Moreover, you have to indicate the directories in which +\texttt{ocamldebug} should search for Caml modules. + +A possible solution is to use a wrapper around \texttt{ocamldebug} +which detects the executables containing the word \texttt{coq}. In +this case, the debugger is called with the required additional +arguments. In other cases, the debugger is simply called without additional +arguments. Such a wrapper can be found in the \texttt{tools/dev} +subdirectory of the sources. + +\section{Modules dependencies}\label{Dependencies}\index{Dependencies} + \index{Coqdep@{\tt coqdep}} + +In order to compute modules dependencies (so to use {\tt make}), +\Coq\ comes with an appropriate tool, {\tt coqdep}. + +{\tt coqdep} computes inter-module dependencies for \Coq\ and +\ocaml\ programs, and prints the dependencies on the standard +output in a format readable by make. When a directory is given as +argument, it is recursively looked at. + +Dependencies of \Coq\ modules are computed by looking at {\tt Require} +commands ({\tt Require}, {\tt Requi\-re Export}, {\tt Require Import}, +{\tt Require Implementation}), but also at the command {\tt Declare ML Module}. + +Dependencies of \ocaml\ modules are computed by looking at +\verb!open! commands and the dot notation {\em module.value}. + +See the man page of {\tt coqdep} for more details and options. + + +\section{Creating a {\tt Makefile} for \Coq\ modules} +\label{Makefile} +\index{Makefile@{\tt Makefile}} +\index{DoMakefile@{\tt do\_Makefile}} + +When a proof development becomes large and is split into several files, +it becomes crucial to use a tool like {\tt make} to compile \Coq\ +modules. + +The writing of a generic and complete {\tt Makefile} may seem tedious +and that's why \Coq\ provides a tool to automate its creation, +{\tt do\_Makefile}. Given the files to compile, the command {\tt +do\_Makefile} prints a +{\tt Makefile} on the standard output. So one has just to run the +command: + +\begin{quotation} +\texttt{\% do\_Makefile} {\em file$_1$.v \dots\ file$_n$.v} \texttt{> Makefile} +\end{quotation} + +The resulted {\tt Makefile} has a target {\tt depend} which computes the +dependencies and puts them in a separate file {\tt .depend}, which is +included by the {\tt Makefile}. +Therefore, you should create such a file before the first invocation +of make. You can for instance use the command + +\begin{quotation} +\texttt{\% touch .depend} +\end{quotation} + +Then, to initialize or update the modules dependencies, type in: + +\begin{quotation} +\texttt{\% make depend} +\end{quotation} + +There is a target {\tt all} to compile all the files {\em file$_1$ +\dots\ file$_n$}, and a generic target to produce a {\tt .vo} file from +the corresponding {\tt .v} file (so you can do {\tt make} {\em file}{\tt.vo} +to compile the file {\em file}{\tt.v}). + +{\tt do\_Makefile} can also handle the case of ML files and +subdirectories. For more options type + +\begin{quotation} +\texttt{\% do\_Makefile --help} +\end{quotation} + +\Warning To compile a project containing \ocaml{} files you must keep +the sources of \Coq{} somewhere and have an environment variable named +\texttt{COQTOP} that points to that directory. + +\section{{\sf Coq\_SearchIsos}: information retrieval in a \Coq\ proofs +library} +\label{coqsearchisos} +\index{Coq\_SearchIsos@{\sf Coq\_SearchIsos}} + +In the \Coq\ distribution, there is also a separated and independent tool, +called {\sf Coq\_SearchIsos}, which allows the search in accordance with {\tt +SearchIsos}\index{SearchIsos@{\tt SearchIsos}} (see section~\ref{searchisos}) +in a \Coq\ proofs library. More precisely, this program begins, once launched +by {\tt coqtop -searchisos}\index{coqtopsearchisos@{\tt +coqtop -searchisos}}, loading lightly (by using specifications functions) +all the \Coq\ objects files ({\tt .vo}) accessible by the {\tt LoadPath} (see +section~\ref{loadpath}). Next, a prompt appears and four commands are then +available: + +\begin{description} +\item [{\tt SearchIsos}]\ \\ + Scans the fixed context. +\item [{\tt Time}]\index{Time@{\tt Time}}\ \\ + Turns on the Time Search Display mode (see section~\ref{time}). +\item [{\tt Untime}]\index{Untime@{\tt Untime}}\ \\ + Turns off the Time Search Display mode (see section~\ref{time}). +\item [{\tt Quit}]\index{Quit@{\tt Quit}}\ \\ + Ends the {\tt coqtop -searchisos} session. +\end{description} + +When running {\tt coqtop -searchisos} you can use the two options: + +\begin{description} +\item[{\tt -opt}]\ \\ + Runs the native-code version of {\sf Coq\_SearchIsos}. + +\item[{\tt -image} {\em file}]\ \\ + This option sets the binary image to be used to be {\em file} + instead of the standard one. Not of general use. +\end{description} + + +\section{\Coq\ and \LaTeX}\label{Latex} + \index{Latex@{\LaTeX}} + +\subsection{Embedded \Coq\ phrases inside \LaTeX\ documents} + \index{Coqtex@{\tt coq-tex}} + +When writing a documentation about a proof development, one may want +to insert \Coq\ phrases inside a \LaTeX\ document, possibly together with +the corresponding answers of the system. We provide a +mechanical way to process such \Coq\ phrases embedded in \LaTeX\ files: the +{\tt coq-tex} filter. This filter extracts Coq phrases embedded in +LaTeX files, evaluates them, and insert the outcome of the evaluation +after each phrase. + +Starting with a file {\em file}{\tt.tex} containing \Coq\ phrases, +the {\tt coq-tex} filter produces a file named {\em file}{\tt.v.tex} with +the \Coq\ outcome. + +There are options to produce the \Coq\ parts in smaller font, italic, +between horizontal rules, etc. +See the man page of {\tt coq-tex} for more details. + +\medskip\noindent {\bf Remark.} This Reference Manual and the Tutorial +have been completely produced with {\tt coq-tex}. + + +\subsection{Pretty printing \Coq\ listings with \LaTeX} + \index{Coq2latex@{\tt coq2latex}} + +\verb!coq2latex! is a tool for printing \Coq\ listings using \LaTeX\ : +keywords are printed in bold face, comments in italic, some tokens +are printed in a nicer way (\verb!->! becomes $\rightarrow$, etc.) +and indentations are kept at the beginning of lines. +Line numbers are printed in the right margin, every 10 lines. + +In regular mode, the command + +\begin{flushleft} +~~~~~\texttt{\% coq2latex {\rm\em file}} +\end{flushleft} + +\noindent produces a \LaTeX\ file which is sent to the \verb!latex! command, +and the result to the \verb!dvips! command. + +It is also possible to get the \LaTeX\ file, DVI file or PostSCript +file, on the standard output or in a file. See the man page of {\tt +coq2latex} for more details and options. + + +\section{\Coq\ and HTML}\label{Html}\index{HTML} + \index{Coq2html@{\tt coq2html}} + +As for \LaTeX, it is also possible to pretty print \Coq\ listing with +HTML. The document looks like the \LaTeX\ one, with links added when +possible : links to other \Coq\ modules in {\tt Require} commands, and +links to identifiers defined in other modules (when they are found in a +path given with {\tt -I} options). + +In regular mode, the command + +\begin{flushleft} +~~~~~\texttt{\% coq2html {\rm\em file}.v} +\end{flushleft} + +\noindent produces an HTML document {{\em file}{\tt .html}}. + +See the man page of {\tt coq2html} for more details and options. + + +\section{\Coq\ and \emacs}\label{Emacs}\index{Emacs} + +\Coq\ comes with a Major mode for \emacs, {\tt coq.el}. This mode provides +syntax highlighting (assuming your \emacs\ library provides +{\tt hilit19.el}) and also a rudimentary indentation facility +in the style of the Caml \emacs\ mode. + +Add the following lines to your \verb!.emacs! file: + +\begin{verbatim} + (setq auto-mode-alist (cons '("\\.v$" . coq-mode) auto-mode-alist)) + (autoload 'coq-mode "coq" "Major mode for editing Coq vernacular." t) +\end{verbatim} + +The \Coq\ major mode is triggered by visiting a file with extension {\tt .v}, +or manually with the command \verb!M-x coq-mode!. +It gives you the correct syntax table for +the \Coq\ language, and also a rudimentary indentation facility: +\begin{itemize} + \item pressing {\sc Tab} at the beginning of a line indents the line like + the line above; + + \item extra {\sc Tab}s increase the indentation level + (by 2 spaces by default); + + \item M-{\sc Tab} decreases the indentation level. +\end{itemize} + + +\section{Module specification}\label{gallina}\index{Gallina@{\tt gallina}} + +Given a \Coq\ vernacular file, the {\tt gallina} filter extracts its +specification (inductive types declarations, definitions, type of +lemmas and theorems), removing the proofs parts of the file. The \Coq\ +file {\em file}{\tt.v} gives birth to the specification file +{\em file}{\tt.g} (where the suffix {\tt.g} stands for {\sf Gallina}). + +See the man page of {\tt gallina} for more details and options. + + +\section{Man pages}\label{ManPages}\index{Man pages} + +There are man pages for the commands {\tt coqtop}, {\tt coqc}, {\tt coqmktop}, +{\tt coqdep}, {\tt gallina},\linebreak{} {\tt coq-tex}, {\tt +coq2latex} and {\tt coq2html}. Man pages are installed at installation time +(see installation instructions in file {\tt INSTALL}, step 6). + +\addtocontents{sh}{ENDREFMAN=\thepage} + +% $Id$ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/doc/Reference-Manual.tex b/doc/Reference-Manual.tex new file mode 100644 index 000000000..1250a580e --- /dev/null +++ b/doc/Reference-Manual.tex @@ -0,0 +1,84 @@ +\documentclass[11pt,a4paper]{book} +\usepackage[T1]{fontenc} +\usepackage[latin1]{inputenc} +\usepackage{verbatim} +\usepackage{palatino} + +\makeatletter + +%\includeonly{Polynom.v} + +\input{./macros.tex}% extension .tex pour htmlgen +\input{./title.tex}% extension .tex pour htmlgen +\input{./headers.tex}% extension .tex pour htmlgen + +\makeatother + +\begin{document} +\tophtml{} +\coverpage{Reference Manual}{Bruno~Barras, Samuel~Boutin, + Cristina~Cornes, Judicaël~Courant, Yann~Coscoy, David~Delahaye, + Daniel~de~Rauglaudre, Jean-Christophe~Filliâtre, Eduardo~Giménez, + Hugo~Herbelin, Gérard~Huet, Henri~Laulhère, César~Muñoz, + Chetan~Murthy, Catherine~Parent-Vigouroux, Patrick~Loiseleur, + Christine~Paulin-Mohring, Amokrane~Saïbi, Benjamin~Werner} + +%\defaultheaders +\include{RefMan-int}% Introduction +\include{RefMan-pre}% Credits + +\tableofcontents + +\part{The language} +\defaultheaders +\include{RefMan-gal.v}% Gallina +\include{RefMan-ext.v}% Gallina extensions +\include{RefMan-lib.v}% The coq library +\include{RefMan-cic.v}% The Calculus of Constructions + +\part{The proof engine} +\include{RefMan-oth}% Vernacular commands +\include{RefMan-pro}% Proof handling +\include{RefMan-tac.v}% Tactics and tacticals +\include{RefMan-tacex.v}% Detailed Examples of tactics + +\part{User extensions} +\include{RefMan-syn.v}% The Syntax and the Grammad commands +\include{RefMan-tus.v}% Writing tactics + +\part{Practical tools} +\include{RefMan-com}% The coq commands (coqc coqtop) +\include{RefMan-uti}% utilities (gallina, do_Makefile, etc) + +\include{AddRefMan-pre}% +\include{Cases.v}% +\include{Coercion.v}% +\include{Natural.v}% +\include{Omega.v}% +\include{Program.v}% +\include{Programs.v}% = preuve de pgms imperatifs +\include{Extraction.v}% +\include{Polynom.v}% = Ring + +\addtocontents{sh}{ENDADDENDUM=\thepage} + +\nocite{*} +\bibliographystyle{plain} +\bibliography{biblio} +\addtocontents{sh}{psselect -q -p-$ENDREFMAN,$BEGINBIBLIO- Reference-Manual.ps Reference-Manual-base.ps} +\addtocontents{sh}{psselect -q -p$BEGINADDENDUM-$ENDADDENDUM Reference-Manual.ps Reference-Manual-addendum.ps} +\addtocontents{sh}{dviselect -i Reference-Manual.dvi -o Reference-Manual-base.dvi 1-$ENDREFMAN $BEGINBIBLIO-} +\addtocontents{sh}{dviselect -i Reference-Manual.dvi -o Reference-Manual-addendum.dvi $BEGINADDENDUM-$ENDADDENDUM} + +\printindex + +\printindex[tactic] + +\printindex[command] + +\printindex[error] + +\end{document} + + +% $Id$ diff --git a/doc/Tutorial-cover.tex b/doc/Tutorial-cover.tex new file mode 100644 index 000000000..832739c3e --- /dev/null +++ b/doc/Tutorial-cover.tex @@ -0,0 +1,50 @@ +\documentstyle[RRcover]{book} + % L'utilisation du style `french' force le résumé français à + % apparaître en premier. +\RRetitle{ +The Coq Proof Assistant \\ A Tutorial \\ Version 6.1 +\thanks{This research was partly supported by ESPRIT Basic Research +Action ``Types'' and by the GDR ``Programmation'' co-financed by MRE-PRC and CNRS.} +} +\RRtitle{Coq \\ Une introduction \\ V6.1 } +\RRauthor{G\'erard Huet, Gilles Kahn and Christine Paulin-Mohring} +\RRtheme{2} +\RRprojet{{Coq +\\[15pt] +{INRIA Rocquencourt} +{\hskip -5.25pt} +~~{\bf ---}~~ + \def\thefootnote{\arabic{footnote}\hss} +{CNRS - ENS Lyon} +\footnote[1]{LIP URA 1398 du CNRS, +46 All\'ee d'Italie, 69364 Lyon CEDEX 07, France.} +{\hskip -14pt}}} + +%\RRNo{0123456789} +\RRNo{0204} +\RRdate{Ao\^ut 1997} + +\URRocq +\RRresume{Coq est un syst\`eme permettant le d\'eveloppement et la +v\'erification de preuves formelles dans une logique d'ordre +sup\'erieure incluant un riche langage de d\'efinitions de fonctions. +Ce document constitue une introduction pratique \`a l'utilisation de +la version V6.1 qui est distribu\'ee par ftp anonyme aux adresses +ftp.inria.fr:/INRIA/Projects/coq/V6.1 et +ftp.ens-lyon.fr:/pub/LIP/COQ/V6.1} + +\RRmotcle{Coq, Syst\`eme d'aide \`a la preuve, Preuves formelles, Calcul +des Constructions Inductives} + +\RRabstract{Coq is a proof assistant based on a higher-order logic +allowing powerful definitions of functions. This document is a +tutorial for the version V6.1 of Coq. This version is available by +anonymous ftp at ftp.inria.fr:/INRIA/Projects/coq/V6.1 and +ftp.ens-lyon.fr:/pub/LIP/COQ/V6.1} + +\RRkeyword{Coq, Proof Assistant, Formal Proofs, Calculus of Inductives +Constructions} + +\begin{document} +\makeRT +\end{document} diff --git a/doc/Tutorial.tex b/doc/Tutorial.tex new file mode 100755 index 000000000..a2459384c --- /dev/null +++ b/doc/Tutorial.tex @@ -0,0 +1,1563 @@ +\documentclass[11pt]{book} +\usepackage[T1]{fontenc} +\usepackage[latin1]{inputenc} +\usepackage{palatino} + +\input{./macros.tex} +\input{./title.tex} + +%\makeindex + +\begin{document} +\coverpage{A Tutorial}{Gérard Huet, Gilles Kahn and Christine Paulin-Mohring} + +%\tableofcontents + +\chapter*{Getting started} + +\Coq\ is a Proof Assistant for a Logical Framework known as the Calculus +of Inductive Constructions. It allows the interactive construction of +formal proofs, and also the manipulation of functional programs +consistently with their specifications. It runs as a computer program +on many architectures, and mainly on Unix machines. It is available +with a variety of user interfaces. The present document does not attempt +to present a comprehensive view of all the possibilities of \Coq, but rather +to present in the most elementary manner a tutorial on the basic +specification language, called Gallina, in which formal axiomatisations +may be developed, and on the main proof tools. + +We assume here that the potential user has installed \Coq~ on his workstation, +that he calls \Coq~ from a standard teletype-like shell window, and that +he does not use any special interface such as Emacs or Centaur. +Instructions on installation procedures, as well as more comprehensive +documentation, may be found in the standard distribution of \Coq, +which may be obtained by anonymous FTP from site \verb:ftp.inria.fr:, +directory \verb:INRIA/coq/V6.3.1:. + +In the following, all examples preceded by the prompting sequence +\verb:Coq < : represent user input, terminated by a period. The +following lines usually show \Coq's answer as it appears on the users's +screen. The sequence of such examples is a valid \Coq~ session, unless +otherwise specified. This version of the tutorial has been prepared +on a SPARC station running UNIX. +The standard invocation of \Coq\ delivers a message such as: + +\begin{small} +\begin{flushleft} +\begin{verbatim} +unix: coqtop +Welcome to Coq V6.3.1 (December 1999) + +Coq < +\end{verbatim} +\end{flushleft} +\end{small} + +The first line gives a banner stating the precise version of \Coq~ +used. You should always return this banner when you report an +anomaly to our hotline \verb:coq@pauillac.inria.fr:. +%The next lines are warnings which may be safely ignored for the time being. + +\chapter{Basic Predicate Calculus} + +\section{An overview of the specification language Gallina} + +A formal development in Gallina consists in a sequence of {\sl declarations} +and {\sl definitions}. You may also send \Coq~ {\sl commands} which are +not really part of the formal development, but correspond to information +requests, or service routine invocations. For instance, the command: +\begin{verbatim} +Coq < Quit. +\end{verbatim} +terminates the current session. + +\subsection{Declarations} + +A declaration associates a {\sl name} with +a {\sl specification}. +A name corresponds roughly to an identifier in a programming +language, i.e. to a string of letters, digits, and a few ASCII symbols like +underscore (\verb"_") and prime (\verb"'"), starting with a letter. +We use case distinction, so that the names \verb"A" and \verb"a" are distinct. +Certain strings are reserved as key-words of \Coq, and thus are forbidden +as user identifiers. + +A specification is a formal expression which classifies the notion which is +being declared. There are basically three kinds of specifications: +{\sl logical propositions}, {\sl mathematical collections}, and +{\sl abstract types}. They are classified by the three basic sorts +of the system, called respectively \verb:Prop:, \verb:Set:, and +\verb:Type:, which are themselves atomic abstract types. + +Every valid expression $e$ in Gallina is associated with a specification, +itself a valid expression, called its {\sl type} $\tau(E)$. We write +$e:\tau(E)$ for the judgement that $e$ is of type $E$. +%CP Le role de \tau n'est pas clair. +You may request \Coq~ to return to you the type of a valid expression by using +the command \verb:Check:: + +\begin{coq_example} +Check O. +\end{coq_example} + +Thus we know that the identifier \verb:O: (the name `O', not to be +confused with the numeral `0' which is not a proper identifier!) is +known in the current context, and that its type is the specification +\verb:nat:. This specification is itself classified as a mathematical +collection, as we may readily check: + +\begin{coq_example} +Check nat. +\end{coq_example} + +The specification \verb:Set: is an abstract type, one of the basic +sorts of the Gallina language, whereas the notions $nat$ and $O$ are +axiomatised notions which are defined in the arithmetic prelude, +automatically loaded when running the \Coq\ system. + +With what we already know, we may now enter in the system a declaration, +corresponding to the informal mathematics {\sl let n be a natural number}: + +\begin{coq_example} +Variable n:nat. +\end{coq_example} + +If we want to translate a more precise statement, such as +{\sl let n be a positive natural number}, +we have to add another declaration, which will declare explicitly the +hypothesis \verb:Pos_n:, with specification the proper logical +proposition: +\begin{coq_example} +Hypothesis Pos_n : (gt n O). +\end{coq_example} + +Indeed we may check that the relation \verb:gt: is known with the right type +in the current context: + +\begin{coq_example} +Check gt. +\end{coq_example} + +which tells us that \verb:gt: is a function expecting two arguments of +type \verb:nat: in order to build a logical proposition. +What happens here is similar to what we are used to in a functional +programming language: we may compose the (specification) type \verb:nat: +with the (abstract) type \verb:Prop: of logical propositions through the +arrow function constructor, in order to get a functional type +\verb:nat->Prop:: +\begin{coq_example} +Check nat->Prop. +\end{coq_example} +which may be composed again with \verb:nat: in order to obtain the +type \verb:nat->nat->Prop: of binary relations over natural numbers. +Actually \verb:nat->nat->Prop: is an abbreviation for +\verb:nat->(nat->Prop):. + +Functional notions may be composed in the usual way. An expression $f$ +of type $A\ra B$ may be applied to an expression $e$ of type $A$ in order +to form the expression $(f~e)$ of type $B$. Here we get that +the expression \verb:(gt n): is well-formed of type \verb:nat->Prop:, +and thus that the expression \verb:(gt n O):, which abbreviates +\verb:((gt n) O):, is a well-formed proposition. +\begin{coq_example} +Check (gt n O). +\end{coq_example} + +\subsection{Definitions} + +The initial prelude contains a few arithmetic definitions: +\verb:nat: is defined as a mathematical collection (type \verb:Set:), constants +\verb:O:, \verb:S:, \verb:plus:, are defined as objects of types +respectively \verb:nat:, \verb:nat->nat:, and \verb:nat->nat->nat:. +You may introduce new definitions, which link a name to a well-typed value. +For instance, we may introduce the constant \verb:one: as being defined +to be equal to the successor of zero: +\begin{coq_example} +Definition one := (S O). +\end{coq_example} +We may optionally indicate the required type: +\begin{coq_example} +Definition two : nat := (S one). +\end{coq_example} + +Actually \Coq~ allows several possible syntaxes: +\begin{coq_example} +Definition three := (S two) : nat. +\end{coq_example} + +Here is a way to define the doubling function, which expects an +argument \verb:m: of type \verb:nat: in order to build its result as +\verb:(plus m m):: + +\begin{coq_example} +Definition double := [m:nat](plus m m). +\end{coq_example} +The abstraction brackets are explained as follows. The expression +\verb+[x:A]e+ is well formed of type \verb+A->B+ in a context +whenever the expression \verb+e+ is well-formed of type \verb+B+ in +the given context to which we add the declaration that \verb+x+ +is of type \verb+A+. Here $x$ is a bound, or dummy variable in +the expression \verb+[x:A]e+. For instance we could as well have +defined \verb:double: as \verb+[n:nat](plus n n)+. + +Bound (local) variables and free (global) variables may be mixed. +For instance, we may define the function which adds the constant \verb:n: +to its argument as +\begin{coq_example} +Definition add_n := [m:nat](plus m n). +\end{coq_example} +However, note that here we may not rename the formal argument $m$ into $n$ +without capturing the free occurrence of $n$, and thus changing the meaning +of the defined notion. + +Binding operations are well known for instance in logic, where they +are called quantifiers. +Thus we may universally quantify a proposition such as $m>0$ in order +to get a universal proposition $\forall m\cdot m>0$. Indeed this +operator is available in \Coq, with the following syntax: +\verb+(m:nat)(gt m O)+. Similarly to the case of the functional abstraction +binding, we are obliged to declare explicitly the type of the quantified +variable. We check: +\begin{coq_example} +Check (m:nat)(gt m O). +\end{coq_example} + +\section{Introduction to the proof engine: Minimal Logic} + +In the following, we are going to consider various propositions, built +from atomic propositions $A, B, C$. This may be done easily, by +introducing these atoms as global variables declared of type \verb:Prop:. +It is easy to declare several names with the same specification: +\begin{coq_example} +Variables A,B,C:Prop. +\end{coq_example} + +We shall consider simple implications, such as $A\ra B$, read as +``$A$ implies $B$''. Remark that we overload the arrow symbol, which +has been used above as the functionality type constructor, and which +may be used as well as propositional connective: +\begin{coq_example} +Check A->B. +\end{coq_example} + +Let us now embark on a simple proof. We want to prove the easy tautology +$((A\ra (B\ra C))\ra (A\ra B)\ra (A\ra C)$. +We enter the proof engine by the command +\verb:Goal:, followed by the conjecture we want to verify: +\begin{coq_example} +Goal (A->(B->C))->(A->B)->(A->C). +\end{coq_example} + +The system displays the current goal below a double line, local hypotheses +(there are none initially) being displayed above the line. We call +the combination of local hypotheses with a goal a {\sl judgement}. +The new prompt \verb:Unnamed_thm <: indicates that we are now in an inner +loop of the system, in proof mode. New commands are available in this +mode, such as {\sl tactics}, which are proof combining primitives. +A tactic operates on the current goal by attempting to construct a proof +of the corresponding judgement, possibly from proofs of some +hypothetical judgements, which are then added to the current +list of conjectured judgements. +For instance, the \verb:Intro: tactic is applicable to any judgement +whose goal is an implication, by moving the proposition to the left +of the application to the list of local hypotheses: +\begin{coq_example} +Intro H. +\end{coq_example} + +%{\bf Warning} to users of \Coq~ previous versions: The display of a sequent in +%older versions of \Coq~ is inverse of this convention: the goal is displayed +%above the double line, the hypotheses below. + +Several introductions may be done in one step: +\begin{coq_example} +Intros H' HA. +\end{coq_example} + +We notice that $C$, the current goal, may be obtained from hypothesis +\verb:H:, provided the truth of $A$ and $B$ are established. +The tactic \verb:Apply: implements this piece of reasoning: +\begin{coq_example} +Apply H. +\end{coq_example} + +We are now in the situation where we have two judgements as conjectures +that remain to be proved. Only the first is listed in full, for the +others the system displays only the corresponding subgoal, without its +local hypotheses list. Remark that \verb:Apply: has kept the local +hypotheses of its father judgement, which are still available for +the judgements it generated. + +In order to solve the current goal, we just have to notice that it is +exactly available as hypothesis $HA$: +\begin{coq_example} +Exact HA. +\end{coq_example} + +Now $H'$ applies: +\begin{coq_example} +Apply H'. +\end{coq_example} + +And we may now conclude the proof as before, with \verb:Exact HA.: +Actually, we may not bother with the name \verb:HA:, and just state that +the current goal is solvable from the current local assumptions: +\begin{coq_example} +Assumption. +\end{coq_example} + +The proof is now finished. We may either discard it, by using the +command \verb:Abort: which returns to the standard \Coq~ toplevel loop +without further ado, or else save it as a lemma in the current context, +under name say \verb:trivial_lemma:: +\begin{coq_example} +Save trivial_lemma. +\end{coq_example} + +As a comment, the system shows the proof script listing all tactic +commands used in the proof. % ligne blanche apres Exact HA?? + +Let us redo the same proof with a few variations. First of all we may name +the initial goal as a conjectured lemma: +\begin{coq_example} +Lemma distr_impl : (A->(B->C))->(A->B)->(A->C). +\end{coq_example} + +%{\bf Warning} to users of \Coq~ older versions: In order to enter the proof +%engine, at this point a dummy \verb:Goal.: command had to be typed in. + +Next, we may omit the names of local assumptions created by the introduction +tactics, they can be automatically created by the proof engine as new +non-clashing names. +\begin{coq_example} +Intros. +\end{coq_example} + +The \verb:Intros: tactic, with no arguments, effects as many individual +applications of \verb:Intro: as is legal. + +Then, we may compose several tactics together in sequence, or in parallel, +through {\sl tacticals}, that is tactic combinators. The main constructions +are the following: +\begin{itemize} +\item $T_1 ; T_2$ (read $T_1$ then $T_2$) applies tactic $T_1$ to the current +goal, and then tactic $T_2$ to all the subgoals generated by $T_1$. +\item $T; [T_1 | T_2 | ... | T_n]$ applies tactic $T$ to the current +goal, and then tactic $T_1$ to the first newly generated subgoal, +..., $T_n$ to the nth. +\end{itemize} + +We may thus complete the proof of \verb:distr_impl: with one composite tactic: +\begin{coq_example} +Apply H; [Assumption | Apply H0; Assumption]. +\end{coq_example} + +Let us now save lemma \verb:distr_impl:: +\begin{coq_example} +Save. +\end{coq_example} + +Here \verb:Save: needs no argument, since we gave the name \verb:distr_impl: +in advance; +it is however possible to override the given name by giving a different +argument to command \verb:Save:. + +Actually, such an easy combination of tactics \verb:Intro:, \verb:Apply: +and \verb:Assumption: may be found completely automatically by an automatic +tactic, called \verb:Auto:, without user guidance: +\begin{coq_example} +Lemma distr_imp : (A->(B->C))->(A->B)->(A->C). +Auto. +\end{coq_example} + +This time, we do not save the proof, we just discard it with the \verb:Abort: +command: + +\begin{coq_example} +Abort. +\end{coq_example} + +At any point during a proof, we may use \verb:Abort: to exit the proof mode +and go back to Coq's main loop. We may also use \verb:Restart: to restart +from scratch the proof of the same lemma. We may also use \verb:Undo: to +backtrack one step, and more generally \verb:Undo n: to +backtrack n steps. + +We end this section by showing a useful command, \verb:Inspect n.:, +which inspects the global \Coq~ environment, showing the last \verb:n: declared +notions: % Attention ici ?? +\begin{coq_example} +Inspect 3. +\end{coq_example} + +The declarations, whether global parameters or axioms, are shown preceded by +\verb:***:; definitions and lemmas are stated with their specification, but +their value (or proof-term) is omitted. + +\section{Propositional Calculus} + +\subsection{Conjunction} + +We have seen that how \verb:Intro: and \verb:Apply: tactics could be combined +in order to prove implicational statements. More generally, \Coq~ favors a style +of reasoning, called {\sl Natural Deduction}, which decomposes reasoning into +so called {\sl introduction rules}, which tell how to prove a goal whose main +operator is a given propositional connective, and {\sl elimination rules}, +which tell how to use an hypothesis whose main operator is the propositional +connective. Let us show how to use these ideas for the propositional connectives +\verb:/\: and \verb:\/:. + +\begin{coq_example} +Lemma and_commutative : A /\ B -> B /\ A. +Intro. +\end{coq_example} + +We make use of the conjunctive hypothesis \verb:H: with the \verb:Elim: tactic, +which breaks it into its components: +\begin{coq_example} +Elim H. +\end{coq_example} + +We now use the conjuction introduction tactic \verb:Split:, which splits the +conjunctive goal into the two subgoals: +\begin{coq_example} +Split. +\end{coq_example} + +and the proof is now trivial. Indeed, the whole proof is obtainable as follows: +\begin{coq_example} +Restart. +Intro H; Elim H; Auto. +Save. +\end{coq_example} + +The tactic \verb:Auto: succeeded here because it knows as a hint the +conjunction introduction operator \verb+conj+ +\begin{coq_example} +Check conj. +\end{coq_example} + +Actually, the tactic \verb+Split+ is just an abbreviation for \verb+Apply conj.+ + +What we have just seen is that the \verb:Auto: tactic is more powerful than +just a simple application of local hypotheses; it tries to apply as well +lemmas which have been specified as hints. A +\verb:Hints Resolve: command registers a +lemma as a hint to be used from now on by the \verb:Auto: tactic, whose power +may thus be incrementally augmented. + +\subsection{Disjunction} + +In a similar fashion, let us consider disjunction: + +\begin{coq_example} +Lemma or_commutative : A \/ B -> B \/ A. +Intro H; Elim H. +\end{coq_example} + +Let us prove the first subgoal in detail. We use \verb:Intro: in order to +be left to prove \verb:B\/A: from \verb:A:: + +\begin{coq_example} +Intro HA. +\end{coq_example} + +Here the hypothesis \verb:H: is not needed anymore. We could choose to +actually erase it with the tactic \verb:Clear:; in this simple proof it +does not really matter, but in bigger proof developments it is useful to +clear away unnecessary hypotheses which may clutter your screen. +\begin{coq_example} +Clear H. +\end{coq_example} + +The disjunction connective has two introduction rules, since \verb:P\/Q: +may be obtained from \verb:P: or from \verb:Q:; the two corresponding +proof constructors are called respectively \verb:or_introl: and +\verb:or_intror:; they are applied to the current goal by tactics +\verb:Left: and \verb:Right: respectively. For instance: +\begin{coq_example} +Right. +Trivial. +\end{coq_example} +%CP Documenter Trivial ou mettre Assumption. + +As before, all these tedious elementary steps may be performed automatically, +as shown for the second symmetric case: + +\begin{coq_example} +Auto. +\end{coq_example} + +However, \verb:Auto: alone does not succeed in proving the full lemma, because +it does not try any elimination step. +It is a bit disappointing that \verb:Auto: is not able to prove automatically +such a simple tautology. The reason is that we want to keep +\verb:Auto: efficient, so that it is always effective to use. + +\subsection{Tauto} + +A complete tactic for propositional +tautologies is indeed available in \Coq~ as the \verb:Tauto: tactic. +%In order to get this facility, we have to import a library module +%called ``Dyckhoff'': +\begin{coq_example} +Restart. +Tauto. +Save. +\end{coq_example} + +It is possible to inspect the actual proof tree constructed by \verb:Tauto:, +using a standard command of the system, which prints the value of any notion +currently defined in the context: +\begin{coq_example} +Print or_commutative. +\end{coq_example} + +It is not easy to understand the notation for proof terms without a few +explanations. The square brackets, such as \verb+[HH1:A\/B]+, correspond +to \verb:Intro HH1:, whereas a subterm such as +\verb:(or_intror: \linebreak \verb:B A HH6): +corresponds to the sequence \verb:Apply or_intror; Exact HH6:. The extra +arguments \verb:B: and \verb:A: correspond to instanciations to the generic +combinator \verb:or_intror:, which are effected automatically by the tactic +\verb:Apply: when pattern-matching a goal. The specialist will of course +recognize our proof term as a $\lambda$-term, used as notation for the +natural deduction proof term through the Curry-Howard isomorphism. The +naive user of \Coq~ may safely ignore these formal details. + +Let us exercise the \verb:Tauto: tactic on a more complex example: +\begin{coq_example} +Lemma distr_and : A->(B/\C) -> (A->B /\ A->C). +Tauto. +Save. +\end{coq_example} + +\subsection{Classical reasoning} + +\verb:Tauto: always comes back with an answer. Here is an example where it +fails: +\begin{coq_example} +Lemma Peirce : ((A->B)->A)->A. +Try Tauto. +\end{coq_example} + +Note the use of the \verb:Try: tactical, which does nothing if its tactic +argument fails. + +This may come as a surprise to someone familiar with classical reasoning. +Peirce's lemma is true in Boolean logic, i.e. it evaluates to \verb:true: for +every truth-assignment to \verb:A: and \verb:B:. Indeed the double negation +of Peirce's law may be proved in \Coq~ using \verb:Tauto:: +\begin{coq_example} +Abort. +Lemma NNPeirce : ~~(((A->B)->A)->A). +Tauto. +Save. +\end{coq_example} + +In classical logic, the double negation of a proposition is equivalent to this +proposition, but in the constructive logic of \Coq~ this is not so. If you +want to use classical logic in \Coq, you have to import explicitly the +\verb:Classical: module, which will declare the axiom \verb:classic: +of excluded middle, and classical tautologies such as de Morgan's laws. +The \verb:Require: command is used to import a module from \Coq's library: +\begin{coq_example} +Require Classical. +Check NNPP. +\end{coq_example} + +and it is now easy (although admittedly not the most direct way) to prove +a classical law such as Peirce's: +\begin{coq_example} +Lemma Peirce : ((A->B)->A)->A. +Apply NNPP; Tauto. +Save. +\end{coq_example} + +Here is one more example of propositional reasoning, in the shape of +a scottish puzzle. A private club has the following rules: +\begin{enumerate} +\item Every non-scottish member wears red socks +\item Every member wears a kilt or doesn't wear red socks +\item The married members don't go out on sunday +\item A member goes out on sunday if and only if he is scottish +\item Every member who wears a kilt is scottish and married +\item Every scottish member wears a kilt +\end{enumerate} +Now, we show that these rules are so strict that no one can be accepted. +\begin{coq_example} +Section club. +Variable Scottish, RedSocks, WearKilt, Married, GoOutSunday : Prop. +Hypothesis rule1 : ~Scottish -> RedSocks. +Hypothesis rule2 : WearKilt \/ ~RedSocks. +Hypothesis rule3 : Married -> ~GoOutSunday. +Hypothesis rule4 : GoOutSunday <-> Scottish. +Hypothesis rule5 : WearKilt -> (Scottish /\ Married). +Hypothesis rule6 : Scottish -> WearKilt. +Lemma NoMember : False. +Tauto. +Save. +End club. +\end{coq_example} + +\section{Predicate Calculus} + +Let us now move into predicate logic, and first of all into first-order +predicate calculus. The essence of predicate calculus is that to try to prove +theorems in the most abstract possible way, without using the definitions of +the mathematical notions, but by formal manipulations of uninterpreted +function and predicate symbols. + +\subsection{Sections and signatures} + +Usually one works in some domain of discourse, over which range the individual +variables and function symbols. In \Coq~ we speak in a language with a rich +variety of types, so me may mix several domains of discourse, in our +multi-sorted language. For the moment, we just do a few exercises, over a +domain of discourse \verb:D: axiomatised as a \verb:Set:, and we consider two +predicate symbols \verb:P: and \verb:R: over \verb:D:, of arities +respectively 1 and 2. Such abstract entities may be entered in the context +as global variables. But we must be careful about the pollution of our +global environment by such declarations. For instance, we have already +polluted our \Coq~ session by declaring the variables +\verb:n:, \verb:Pos_n:, \verb:A:, \verb:B:, and \verb:C:. If we want to revert to the clean state of +our initial session, we may use the \Coq~ \verb:Reset: command, which returns +to the state just prior the given global notion. +\begin{coq_example} +Reset n. +\end{coq_example} +%CP-Parler de Reset Initial. + +We shall now declare a new \verb:Section:, which will allow us to define +notions local to a well-delimited scope. We start by assuming a domain of +discourse \verb:D:, and a binary relation \verb:R: over \verb:D:: +\begin{coq_example} +Section Predicate_calculus. +Variable D:Set. +Variable R: D -> D -> Prop. +\end{coq_example} + +As a simple example of predicate calculus reasoning, let us assume +that relation \verb:R: is symmetric and transitive, and let us show that +\verb:R: is reflexive in any point \verb:x: which has an \verb:R: successor. +Since we do not want to make the assumptions about \verb:R: global axioms of +a theory, but rather local hypotheses to a theorem, we open a specific +section to this effect. +\begin{coq_example} +Section R_sym_trans. +Hypothesis R_symmetric : (x,y:D) (R x y) -> (R y x). +Hypothesis R_transitive : (x,y,z:D) (R x y) -> (R y z) -> (R x z). +\end{coq_example} + +Remark the syntax \verb+(x:D)+ which stands for universal quantification +$\forall x : D$. + +\subsection{Existential quantification} + +We now state our lemma, and enter proof mode. +\begin{coq_example} +Lemma refl_if : (x:D)(EX y | (R x y)) -> (R x x). +\end{coq_example} + +Remark that the hypotheses which are local to the currently opened sections +are listed as local hypotheses to the current goals. +The rationale is that these hypotheses are going to be discharged, as we +shall see, when we shall close the corresponding sections. + +Note the functional syntax for existential quantification. The existential +quantifier is built from the operator \verb:ex:, which expects a +predicate as argument: +\begin{coq_example} +Check ex. +\end{coq_example} +and the notation \verb+(EX x | (P x))+ is just concrete syntax for +\verb+(ex D [x:D](P x))+. +Existential quantification is handled in \Coq~ in a similar +fashion to the connectives \verb:/\: and \verb:\/: : it is introduced by +the proof combinator \verb:ex_intro:, which is invoked by the specific +tactic \verb:Exists:, and its elimination provides a witness \verb+a:D+ to +\verb:P:, together with an assumption \verb+h:(P a)+ that indeed \verb+a+ +verifies \verb:P:. Let us see how this works on this simple example. +\begin{coq_example} +Intros x x_Rlinked. +\end{coq_example} + +Remark that \verb:Intro: treats universal quantification in the same way +as the premisses of implications. Renaming of bound variables occurs +when it is needed; for instance, had we started with \verb:Intro y:, +we would have obtained the goal: +\begin{coq_eval} +Undo. +\end{coq_eval} +\begin{coq_example} +Intro y. +\end{coq_example} +\begin{coq_eval} +Undo. +Intros x x_Rlinked. +\end{coq_eval} + +Let us now use the existential hypothesis \verb:x_Rlinked: to +exhibit an R-successor y of x. This is done in two steps, first with +\verb:Elim:, then with \verb:Intros: + +\begin{coq_example} +Elim x_Rlinked. +Intros y Rxy. +\end{coq_example} + +Now we want to use \verb:R_transitive:. The \verb:Apply: tactic will know +how to match \verb:x: with \verb:x:, and \verb:z: with \verb:x:, but needs +help on how to instanciate \verb:y:, which appear in the hypotheses of +\verb:R_transitive:, but not in its conclusion. We give the proper hint +to \verb:Apply: in a \verb:with: clause, as follows: +\begin{coq_example} +Apply R_transitive with y. +\end{coq_example} + +The rest of the proof is routine: +\begin{coq_example} +Assumption. +Apply R_symmetric; Assumption. +\end{coq_example} +\begin{coq_example*} +Save. +\end{coq_example*} + +Let us now close the current section. +\begin{coq_example} +End R_sym_trans. +\end{coq_example} + +Here \Coq's printout is a warning that all local hypotheses have been +discharged in the statement of \verb:refl_if:, which now becomes a general +theorem in the first-order language declared in section +\verb:Predicate_calculus:. In this particular example, the use of section +\verb:R_sym_trans: has not been really significant, since we could have +instead stated theorem \verb:refl_if: in its general form, and done +basically the same proof, obtaining \verb:R_symmetric: and +\verb:R_transitive: as local hypotheses by initial \verb:Intros: rather +than as global hypotheses in the context. But if we had pursued the +theory by proving more theorems about relation \verb:R:, +we would have obtained all general statements at the closing of the section, +with minimal dependencies on the hypotheses of symmetry and transitivity. + +\subsection{Paradoxes of classical predicate calculus} + +Let us illustrate this feature by pursuing our \verb:Predicate_calculus: +section with an enrichment of our language: we declare a unary predicate +\verb:P: and a constant \verb:d:: +\begin{coq_example} +Variable P:D->Prop. +Variable d:D. +\end{coq_example} + +We shall now prove a well-known fact from first-order logic: a universal +predicate is non-empty, or in other terms existential quantification +follows from universal quantification. +\begin{coq_example} +Lemma weird : ((x:D)(P x)) -> (EX a | (P a)). +Intro UnivP. +\end{coq_example} + +First of all, notice the pair of parentheses around \verb+(x:D)(P x)+ in +the statement of lemma \verb:weird:. +If we had ommitted them, \Coq's parser would have interpreted the +statement as a truly trivial fact, since we would +postulate an \verb:x: verifying \verb:(P x):. Here the situation is indeed +more problematic. If we have some element in \verb:Set: \verb:D:, we may +apply \verb:UnivP: to it and conclude, otherwise we are stuck. Indeed +such an element \verb:d: exists, but this is just by virtue of our +new signature. This points out a subtle difference between standard +predicate calculus and \Coq. In standard first-order logic, +the equivalent of lemma \verb:weird: always holds, +because such a rule is wired in the inference rules for quantifiers, the +semantic justification being that the interpretation domain is assumed to +be non-empty. Whereas in \Coq, where types are not assumed to be +systematically inhabited, lemma \verb:weird: only holds in signatures +which allow the explicit construction of an element in the domain of +the predicate. + +Let us conclude the proof, in order to show the use of the \verb:Exists: +tactic: +\begin{coq_example} +Exists d; Trivial. +Save. +\end{coq_example} + +Another fact which illustrates the sometimes disconcerting rules of +classical +predicate calculus is Smullyan's drinkers' paradox: ``In any non-empty +bar, there is a person such that if she drinks, then everyone drinks''. +We modelize the bar by Set \verb:D:, drinking by predicate \verb:P:. +We shall need classical reasoning. Instead of loading the \verb:Classical: +module as we did above, we just state the law of excluded middle as a +local hypothesis schema at this point: +\begin{coq_example} +Hypothesis EM : (A:Prop) A \/ ~A. +Lemma drinker : (EX x | (P x) -> (x:D)(P x)). +\end{coq_example} +The proof goes by cases on whether or not +there is someone who does not drink. Such reasoning by cases proceeds +by invoking the excluded middle principle, via \verb:Elim: of the +proper instance of \verb:EM:: +\begin{coq_example} +Elim (EM (EX x | ~(P x))). +\end{coq_example} + +We first look at the first case. Let Tom be the non-drinker: +\begin{coq_example} +Intro Non_drinker; Elim Non_drinker; Intros Tom Tom_does_not_drink. +\end{coq_example} + +We conclude in that case by considering Tom, since his drinking leads to +a contradiction: +\begin{coq_example} +Exists Tom; Intro Tom_drinks. +\end{coq_example} + +There are several ways in which we may eliminate a contradictory case; +a simple one is to use the \verb:Absurd: tactic as follows: +\begin{coq_example} +Absurd (P Tom); Trivial. +\end{coq_example} + +We now proceed with the second case, in which actually any person will do; +such a John Doe is given by the non-emptyness witness \verb:d:: +\begin{coq_example} +Intro No_nondrinker; Exists d; Intro d_drinks. +\end{coq_example} + +Now we consider any Dick in the bar, and reason by cases according to its +drinking or not: +\begin{coq_example} +Intro Dick; Elim (EM (P Dick)); Trivial. +\end{coq_example} + +The only non-trivial case is again treated by contradiction: +\begin{coq_example} +Intro Dick_does_not_drink; Absurd (EX x | ~(P x)); Trivial. +Exists Dick; Trivial. +Save. +\end{coq_example} + +Now, let us close the main section: +\begin{coq_example} +End Predicate_calculus. +\end{coq_example} + +Remark how the three theorems are completely generic is the most general +fashion; +the domain \verb:D: is discharged in all of them, \verb:R: is discharged in +\verb:refl_if: only, \verb:P: is discharged only in \verb:weird: and +\verb:drinker:, along with the hypothesis that \verb:D: is inhabited. +Finally, the excluded middle hypothesis is discharged only in +\verb:drinker:. + +Note that the name \verb:d: has vanished as well from +the statements of \verb:weird: and \verb:drinker:, +since \Coq's prettyprinter replaces +systematically a quantification such as \verb+(d:D)E+, where \verb:d: +does not occur in \verb:E:, by the functional notation \verb:D->E:. +Similarly the name \verb:EM: does not appear in \verb:drinker:. + +Actually, universal quantification, implication, +as well as function formation, are +all special cases of one general construct of type theory called +{\sl dependent product}. This is the mathematical construction +corresponding to an indexed family of functions. A function +$f\in \Pi x:D\cdot Cx$ maps an element $x$ of its domain $D$ to its +(indexed) codomain $Cx$. Thus a proof of $\forall x:D\cdot Px$ is +a function mapping an element $x$ of $D$ to a proof of proposition $Px$. + + +\subsection{Flexible use of local assumptions} + +Very often during the course of a proof we want to retrieve a local +assumption and reintroduce it explicitly in the goal, for instance +in order to get a more general induction hypothesis. The tactic +\verb:Generalize: is what is needed here: + +\begin{coq_example} +Variable P,Q:nat->Prop. Variable R: nat->nat->Prop. +Lemma PQR : (x,y:nat)((R x x)->(P x)->(Q x))->(P x)->(R x y)->(Q x). +Intros. +Generalize H0. +\end{coq_example} + +Sometimes it may be convenient to use a lemma, although we do not have +a direct way to appeal to such an already proven fact. The tactic \verb:Cut: +permits to use the lemma at this point, keeping the corresponding proof +obligation as a new subgoal: +\begin{coq_example} +Cut (R x x); Trivial. +\end{coq_example} +%CP pourquoi ne pas montrer les deux sous-buts engendres par Cut. + +\subsection{Equality} + +The basic equality provided in \Coq~ is Leibniz equality, noted infix like +\verb+x=y+, when \verb:x: and \verb:y: are two expressions of +type the same Set. The replacement of \verb:x: by \verb:y: in any +term is effected by a variety of tactics, such as \verb:Rewrite: +and \verb:Replace:. + +Let us give a few examples of equality replacement. Let us assume that +some arithmetic function \verb:f: is null in zero: +\begin{coq_example} +Variable f:nat->nat. +Hypothesis foo : (f O)=O. +\end{coq_example} + +We want to prove the following conditional equality: +\begin{coq_example*} +Lemma L1 : (k:nat)k=O->(f k)=k. +\end{coq_example*} + +As usual, we first get rid of local assumptions with \verb:Intro:: +\begin{coq_example} +Intros k E. +\end{coq_example} + +Let us now use equation \verb:E: as a left-to-right rewriting: +\begin{coq_example} +Rewrite E. +\end{coq_example} +This replaced both occurrences of \verb:k: by \verb:O:. + +\medskip +{\bf Warning} to users of \Coq~ old versions: In \Coq V5.8 only the second +occurrence of \verb:k: would have been replaced, and we would have had +to use \verb:Rewrite: twice in order to get the same effect. +\medskip + +%Actually, it is possible to rewrite both occurrences of \verb:k: at the +%same time, provided one abstracts \verb:k: in the goal with tactic +%\verb:Pattern:. Let us go back two steps: +%\begin{coq_example} +%L1 < Undo 2. +%1 subgoal +% +% k : nat +% E : k=O +% ============================ +% (f k)=k +% +%L1 < Pattern k. +%1 subgoal +% +% k : nat +% E : k=O +% ============================ +% ([n:nat](f n)=n k) +%\end{coq_example} +%What just happened is that \verb:Pattern: replaced the goal +%\verb:(f k)=k: by the equivalent one: +%\verb+([n:nat](f n)=n k)+, which has the form \verb+(P k)+, with +%\verb+P+ the predicate which maps \verb+n+ to proposition +%\verb+(f n)=n+. The two goals are equivalent in the sense that +%\verb+([n:nat](f n)=n k)+ {\sl reduces} to \verb:(f k)=k: +%by the following computation rule: +%$$ ([x:A]M~N) \leftarrow M\{x/N\} \eqno \beta$$ +%We may now proceed with our rewriting: +%\begin{coq_example} +%L1 < Rewrite E. +%1 subgoal +% +% k : nat +% E : k=O +% ============================ +% (f O)=O + +Now \verb:Apply foo: will finish the proof: + +\begin{coq_example} +Apply foo. +Save. +\end{coq_example} + +When one wants to rewrite an equality in a right to left fashion, we should +use \verb:Rewrite <- E: rather than \verb:Rewrite E: or the equivalent +\verb:Rewrite -> E:. +Let us now illustrate the tactic \verb:Replace:. +\begin{coq_example} +Lemma L2 : (f (f O))=O. +Replace (f O) with O. +\end{coq_example} +What happened here is that the replacement left the first subgoal to be +proved, but another proof obligation was generated by the \verb:Replace: +tactic, as the second subgoal. The first subgoal is solved immediately +by appying lemma \verb:foo:; the second one too, provided we apply first +symmetry of equality, for instance with tactic \verb:Symmetry:: +\begin{coq_example} +Apply foo. +Symmetry; Apply foo. +Save. +\end{coq_example} + +\subsection{Predicate calculus over Type} + +We just explained the basis of first-order reasoning in the universe +of mathematical Sets. Similar reasoning is available at the level of +abstract Types. In order to develop such abtract reasoning, one must +load the library \verb:Logic_Type:. + +\begin{coq_example} +Require Logic_Type. +\end{coq_example} + +New proof combinators are now available, such as the existential +quantification \verb:exT: over a Type, available with syntax +\verb:(EXT x | (P x)):. The corresponding introduction +combinator may be invoked by the tactic \verb:Exists: as above. +\begin{coq_example} +Check exT_intro. +\end{coq_example} + +Similarly, equality over Type is available, with notation +\verb:M==N:. The equality tactics process \verb:==: in the same way +as \verb:=:. + +\section{Using definitions} + +The development of mathematics does not simply proceed by logical +argumentation from first principles: definitions are used in an essential way. +A formal development proceeds by a dual process of abstraction, where one +proves abstract statements in predicate calculus, and use of definitions, +which in the contrary one instanciates general statements with particular +notions in order to use the structure of mathematical values for the proof of +more specialised properties. + +\subsection{Unfolding definitions} + +Assume that we want to develop the theory of sets represented as characteristic +predicates over some universe \verb:U:. For instance: +%CP Une petite explication pour le codage de element ? +\begin{coq_example} +Variable U:Type. +Definition set := U->Prop. +Definition element := [x:U][S:set](S x). +Definition subset := [A,B:set](x:U)(element x A)->(element x B). +\end{coq_example} + +Now, assume that we have loaded a module of general properties about +relations over some abstract type \verb:T:, such as transitivity: + +\begin{coq_example} +Definition transitive := [T:Type][R:T->T->Prop] + (x,y,z:T)(R x y)->(R y z)->(R x z). +\end{coq_example} + +Now, assume that we want to prove that \verb:subset: is a \verb:transitive: +relation. +\begin{coq_example} +Lemma subset_transitive : (transitive set subset). +\end{coq_example} + +In order to make any progress, one needs to use the definition of +\verb:transitive:. The \verb:Unfold: tactic, which replaces all occurrences of a +defined notion by its definition in the current goal, may be used here. +\begin{coq_example} +Unfold transitive. +\end{coq_example} + +Now, we must unfold \verb:subset:: +\begin{coq_example} +Unfold subset. +\end{coq_example} +Now, unfolding \verb:element: would be a mistake, because indeed a simple proof +can be found by \verb:Auto:, keeping \verb:element: an abstract predicate: +\begin{coq_example} +Auto. +\end{coq_example} + +Many variations on \verb:Unfold: are provided in \Coq. For instance, +we may selectively unfold one designated occurrence: +\begin{coq_example} +Undo 2. +Unfold 2 subset. +\end{coq_example} + +One may also unfold a definition in a given local hypothesis, using the +\verb:in: notation: +\begin{coq_example} +Intros. +Unfold subset in H. +\end{coq_example} + +Finally, the tactic \verb:Red: does only unfolding of the head occurrence +of the current goal: +\begin{coq_example} +Red. +Auto. Save. +\end{coq_example} + + +\subsection{Principle of proof irrelevance} + +Even though in principle the proof term associated with a verified lemma +corresponds to a defined value of the corresponding specification, such +definitions cannot be unfolded in \Coq: a lemma is considered an {\sl opaque} +definition. This conforms to the mathematical tradition of {\sl proof +irrelevance}: the proof of a logical proposition does not matter, and the +mathematical justification of a logical development relies only on +{\sl provability} of the lemmas used in the formal proof. + +Conversely, ordinary mathematical definitions can be unfolded at will, they +are {\sl transparent}. It is possible to enforce the reverse convention by +declaring a definition as {\sl opaque} or a lemma as {\sl transparent}. + +\chapter{Induction} + +\section{Data Types as Inductively Defined Mathematical Collections} + +All the notions which were studied until now pertain to traditional +mathematical logic. Specifications of objects were abstract properties +used in reasoning more or less constructively; we are now entering +the realm of inductive types, which specify the existence of concrete +mathematical constructions. + +\subsection{Booleans} + +Let us start with the collection of booleans, as they are specified +in the \Coq's \verb:Prelude: module: +\begin{coq_example} +Inductive bool : Set := true : bool | false : bool. +\end{coq_example} + +Such a declaration defines several objects at once. First, a new +\verb:Set: is declared, with name \verb:bool:. Then the {\sl constructors} +of this \verb:Set: are declared, called \verb:true: and \verb:false:. +Those are analogous to introduction rules of the new Set \verb:bool:. +Finally, a specific elimination rule for \verb:bool: is now available, which +permits to reason by cases on \verb:bool: values. Three instances are +indeed defined as new combinators in the global context: \verb:bool_ind:, +a proof combinator corresponding to reasoning by cases, +\verb:bool_rec:, an if-then-else programming construct, +and \verb:bool_rect:, a similar combinator at the level of types. +Indeed: +\begin{coq_example} +Check bool_ind. +Check bool_rec. +Check bool_rect. +\end{coq_example} + +Let us for instance prove that every Boolean is true or false. +\begin{coq_example} +Lemma duality : (b:bool)(b=true \/ b=false). +Intro b. +\end{coq_example} + +We use the knowledge that \verb:b: is a \verb:bool: by calling tactic +\verb:Elim:, which is this case will appeal to combinator \verb:bool_ind: +in order to split the proof according to the two cases: +\begin{coq_example} +Elim b. +\end{coq_example} + +It is easy to conclude in each case: +\begin{coq_example} +Left; Trivial. +Right; Trivial. +\end{coq_example} + +Indeed, the whole proof can be done with the combination of the +\verb:Induction: tactic, which combines \verb:Intro: and \verb:Elim:, +with good old \verb:Auto:: +\begin{coq_example} +Restart. +Induction b; Auto. +Save. +\end{coq_example} + +\subsection{Natural numbers} + +Similarly to Booleans, natural numbers are defined in the \verb:Prelude: +module with constructors \verb:S: and \verb:O:: +\begin{coq_example} +Inductive nat : Set := O : nat | S : nat->nat. +\end{coq_example} + +The elimination principles which are automatically generated are Peano's +induction principle, and a recursion operator: +\begin{coq_example} +Check nat_ind. +Check nat_rec. +\end{coq_example} + +Let us start by showing how to program the standard primitive recursion +operator \verb:prim_rec: from the more general \verb:nat_rec:: +\begin{coq_example} +Definition prim_rec := (nat_rec [i:nat]nat). +\end{coq_example} + +That is, instead of computing for natural \verb:i: an element of the indexed +\verb:Set: \verb:(P i):, \verb:prim_rec: computes uniformly an element of +\verb:nat:. Let us check the type of \verb:prim_rec:: +\begin{coq_example} +Check prim_rec. +\end{coq_example} + +Oops! Instead of the expected type \verb+nat->(nat->nat->nat)->nat->nat+ we +get an apparently more complicated expression. Indeed the type of +\verb:prim_rec: is equivalent by rule $\beta$ to its expected type; this may +be checked in \Coq~ by command \verb:Eval Cbv Beta:, which $\beta$-reduces +an expression to its {\sl normal form}: +\begin{coq_example} +Eval Cbv Beta in + ([_:nat]nat O) + ->((y:nat)([_:nat]nat y)->([_:nat]nat (S y))) + ->(n:nat)([_:nat]nat n). +\end{coq_example} + +Let us now show how to program addition with primitive recursion: +\begin{coq_example} +Definition addition := [n,m:nat](prim_rec m [p:nat][rec:nat](S rec) n). +\end{coq_example} + +That is, we specify that \verb+(addition n m)+ computes by cases on \verb:n: +according to its main constructor; when \verb:n=O:, we get \verb:m:; + when \verb:n=(S p):, we get \verb:(S rec):, where \verb:rec: is the result +of the recursive computation \verb+(addition p m)+. Let us verify it by +asking \Coq~to compute for us say $2+3$: +\begin{coq_example} +Eval Compute in (addition (S (S O)) (S (S (S O)))). +\end{coq_example} + +Actually, we do not have to do all explicitly. {\Coq} provides a +special syntax {\tt Fixpoint/Cases} for generic primitive recursion, +and we could thus have defined directly addition as: + +\begin{coq_example} +Fixpoint plus [n:nat] : nat -> nat := + [m:nat]Cases n of + O => m + | (S p) => (S (plus p m)) + end. +\end{coq_example} + +For the rest of the session, we shall clean up what we did so far with +types \verb:bool: and \verb:nat:, in order to use the initial definitions +given in \Coq's \verb:Prelude: module, and not to get confusing error +messages due to our redefinitions. We thus revert to the state before +our definition of \verb:bool: with the \verb:Reset: command: +\begin{coq_example} +Reset bool. +\end{coq_example} + + +\subsection{Simple proofs by induction} +%CP Pourquoi ne pas commencer par des preuves d'egalite entre termes +% convertibles. + +Let us now show how to do proofs by structural induction. We start with easy +properties of the \verb:plus: function we just defined. Let us first +show that $n=n+0$. +\begin{coq_example} +Lemma plus_n_O : (n:nat)n=(plus n O). +Intro n; Elim n. +\end{coq_example} + +What happened was that \verb:Elim n:, in order to construct a \verb:Prop: +(the initial goal) from a \verb:nat: (i.e. \verb:n:), appealed to the +corresponding induction principle \verb:nat_ind: which we saw was indeed +excactly Peano's induction scheme. Pattern-matching instanciated the +corresponding predicate \verb:P: to \verb+[n:nat]n=(plus n O)+, and we get +as subgoals the corresponding instanciations of the base case \verb:(P O): , +and of the inductive step \verb+(y:nat)(P y)->(P (S y))+. +In each case we get an instance of function \verb:plus: in which its second +argument starts with a constructor, and is thus amenable to simplification +by primitive recursion. The \Coq~tactic \verb:Simpl: can be used for +this purpose: +\begin{coq_example} +Simpl. +Auto. +\end{coq_example} + +We proceed in the same way for the base step: +\begin{coq_example} +Simpl; Auto. +Save. +\end{coq_example} + +Here \verb:Auto: succeded, because it used as a hint lemma \verb:eq_S:, +which say that successor preserves equality: +\begin{coq_example} +Check eq_S. +\end{coq_example} + +Actually, let us see how to declare our lemma \verb:plus_n_O: as a hint +to be used by \verb:Auto:: +\begin{coq_example} +Hints Resolve plus_n_O. +\end{coq_example} + +We now proceed to the similar property concerning the other constructor +\verb:S:: +\begin{coq_example} +Lemma plus_n_S : (n,m:nat)(S (plus n m))=(plus n (S m)). +\end{coq_example} + +We now go faster, remembering that tactic \verb:Induction: does the +necessary \verb:Intros: before applying \verb:Elim:. Factoring simplification +and automation in both cases thanks to tactic composition, we prove this +lemma in one line: +\begin{coq_example} +Induction n; Simpl; Auto. +Save. +Hints Resolve plus_n_S. +\end{coq_example} + +Let us end this exercise with the commutativity of \verb:plus:: + +\begin{coq_example} +Lemma plus_com : (n,m:nat)(plus n m)=(plus m n). +\end{coq_example} + +Here we have a choice on doing an induction on \verb:n: or on \verb:m:, the +situation being symmetric. For instance: +\begin{coq_example} +Induction m; Simpl; Auto. +\end{coq_example} + +Here \verb:Auto: succeded on the base case, thanks to our hint \verb:plus_n_O:, +but the induction step requires rewriting, which \verb:Auto: does not handle: + +\begin{coq_example} +Intros m' E; Rewrite <- E; Auto. +Save. +\end{coq_example} + +%CP - non ce n'est pas un bon exemple de Immediate. +%A symmetric lemma such \verb:plus_com: should not be declared as a hint, +%because \verb:Auto: would lose time by applying it repeatedly without progress. +%A variant of command \verb:Hint:, called \verb:Immediate:, allows a restricted +%use of such lemmas: +%\begin{coq_example} +%Immediate plus_com. +%\end{coq_example} + +\subsection{Discriminate} + +It is also possible to define new propositions by primitive recursion. +Let us for instance define the predicate which discriminates between +the constructors \verb:O: and \verb:S:: it computes to \verb:False: +when its argument is \verb:O:, and to \verb:True: when its argument is +of the form \verb:(S n):: +\begin{coq_example} +Definition Is_S + := [n:nat]Cases n of O => False | (S p) => True end. +\end{coq_example} + +Now we may use the computational power of \verb:Is_S: in order to prove +trivially that \verb:(Is_S (S n)):: +\begin{coq_example} +Lemma S_Is_S : (n:nat)(Is_S (S n)). +Simpl; Trivial. +Save. +\end{coq_example} + +But we may also use it to transform a \verb:False: goal into +\verb:(Is_S O):. Let us show a particularly important use of this feature; +we want to prove that \verb:O: and \verb:S: construct different values, one +of Peano's axioms: +\begin{coq_example} +Lemma no_confusion : (n:nat)~(O=(S n)). +\end{coq_example} + +First of all, we replace negation by its definition, by reducing the +goal with tactic \verb:Red:; then we get contradiction by successive +\verb:Intros:: +\begin{coq_example} +Red; Intros n H. +\end{coq_example} + +Now we use our trick: +\begin{coq_example} +Change (Is_S O). +\end{coq_example} + +Now we use equality in order to get a subgoal which computes out to +\verb:True:, which finishes the proof: +\begin{coq_example} +Rewrite H; Trivial. +Simpl; Trivial. +\end{coq_example} + +Actually, a specific tactic \verb:Discriminate: is provided +to produce mechanically such proofs, without the need for the user to define +explicitly the relevant discrimination predicates: + +\begin{coq_example} +Restart. +Intro n; Discriminate. +Save. +\end{coq_example} + + +\section{Logic programming} + +In the same way as we defined standard data-types above, we +may define inductive families, and for instance inductive predicates. +Here is the definition of predicate $\le$ over type \verb:nat:, as +given in \Coq's \verb:Prelude: module: +\begin{coq_example*} +Inductive le [n:nat] : nat -> Prop + := le_n : (le n n) + | le_S : (m:nat)(le n m)->(le n (S m)). +\end{coq_example*} + +This definition introduces a new predicate \verb+le:nat->nat->Prop+, +and the two constructors \verb:le_n: and \verb:le_S:, which are the +defining clauses of \verb:le:. That is, we get not only the ``axioms'' +\verb:le_n: and \verb:le_S:, but also the converse property, that +\verb:(le n m): if and only if this statement can be obtained as a +consequence of these defining clauses; that is, \verb:le: is the +minimal predicate verifying clauses \verb:le_n: and \verb:le_S:. This is +insured, as in the case of inductive data types, by an elimination principle, +which here amounts to an induction principle \verb:le_ind:, stating this +minimality property: +\begin{coq_example} +Check le. +Check le_ind. +\end{coq_example} + +Let us show how proofs may be conducted with this principle. +First we show that $n\le m \Rightarrow n+1\le m+1$: +\begin{coq_example} +Lemma le_n_S : (n,m:nat)(le n m)->(le (S n) (S m)). +Intros n m n_le_m. +Elim n_le_m. +\end{coq_example} + +What happens here is similar to the behaviour of \verb:Elim: on natural +numbers: it appeals to the relevant induction principle, here \verb:le_ind:, +which generates the two subgoals, which may then be solved easily +%as if ``backchaining'' the current goal +with the help of the defining clauses of \verb:le:. +\begin{coq_example} +Apply le_n; Trivial. +Intros; Apply le_S; Trivial. +\end{coq_example} + +Now we know that it is a good idea to give the defining clauses as hints, +so that the proof may proceed with a simple combination of +\verb:Induction: and \verb:Auto:. +\begin{coq_example} +Restart. +Hints Resolve le_n le_S. +\end{coq_example} + +We have a slight problem however. We want to say ``Do an induction on +hypothesis \verb:(le n m):'', but we have no explicit name for it. What we +do in this case is to say ``Do an induction on the first unnamed hypothesis'', +as follows. +\begin{coq_example} +Induction 1; Auto. +Save. +\end{coq_example} + +Here is a more tricky problem. Assume we want to show that +$n\le 0 \Rightarrow n=0$. This reasoning ought to follow simply from the +fact that only the first defining clause of \verb:le: applies. +\begin{coq_example} +Lemma tricky : (n:nat)(le n O)->n=O. +\end{coq_example} + +However, here trying something like \verb:Induction 1: would lead +nowhere (try it and see what happens). +An induction on \verb:n: would not be convenient either. +What we must do here is analyse the definition of \verb"le" in order +to match hypothesis \verb:(le n O): with the defining clauses, to find +that only \verb:le_n: applies, whence the result. +This analysis may be performed by the ``inversion'' tactic +\verb:Inversion_clear: as follows: +\begin{coq_example} +Intros n H; Inversion_clear H. +Trivial. +Save. +\end{coq_example} + +\chapter{Modules} + +\section{Opening library modules} + +When you start \Coq~ without further requirements in the command line, +you get a bare system with few libraries loaded. As we saw, a standard +prelude module provides the standard logic connectives, and a few +arithmetic notions. If you want to load and open other modules from +the library, you have to use the \verb"Require" command, as we saw for +classical logic above. For instance, if you want more arithmetic +constructions, you should request: +\begin{coq_example*} +Require Arith. +\end{coq_example*} + +Such a command looks for a (compiled) module file \verb:Arith.vo: +on the current \verb:LoadPath:. This loadpath may be changed +with the commands \verb:AddPath: and \verb:DelPath:. + +The loading of such a compiled file is quick, because the corresponding +development is not typechecked again. This is a great saving compared +to previous versions of our proof assistant. + +If you want to recursively import modules which are required for module +M, you should use \verb:Require Export M:. + +{\bf Warning} \Coq~ does not yet provides parametric modules. + +\section{Creating your own modules} + +You may create your own modules, by writing \Coq~ commands in a file, +say \verb:my_module.v:. Such a module may be simply loaded in the current +context, with command \verb:Load my_module:. It may also be compiled, +using the command \verb:Compile Module my_module: directly at the +\Coq~ toplevel, or else in ``batch'' mode, using the UNIX command +\verb:coqc:. Compiling the module \verb:my_module.v: creates a +file \verb:my_module.vo: that can be reloaded with command +\verb:Require my_module:. + +%CP- Non compatible avec la version distribuee. +%Compiling a module creates actually 2 files in the current version: +%\verb:my_module.vi: and \verb:my_module.vo:. This last file is +%bigger, because it stores the value of opaque constants, such as the +%proofs of lemmas. If you want to be able to turn such constants as +%transparent constants (whose definition may be unfolded), you must +%use the command \verb:Require Implementation my_module:. + +\section{Managing the context} + +It is often difficult to remember the names of all lemmas and +definitions available in the current context, especially if large +libraries have been loaded. A convenient \verb:Search: command +is available to lookup all known facts +concerning a given predicate. For instance, if you want to know all the +known lemmas about the less or equal relation, juste ask: +\begin{coq_example} +Search le. +\end{coq_example} + +A new and more convenient search tool is \textsf{SearchIsos}. The +argument to give is a type and it searches in the current context all +constants having the same type modulo certain notion of +\textit{isomorphism}. For example~: + +\begin{coq_example} +Require Arith. +SearchIsos nat -> nat -> Prop. +SearchIsos (x,y,z:nat)(le x y) -> (le y z) -> (le x z). +\end{coq_example} + +\section{Now you are on your own} + +This tutorial is necessarily incomplete. If you wish to pursue serious +proving in \Coq, you should now get your hands on \Coq's Reference Manual, +which contains a complete description of all the tactics we saw, +plus many more. +You also should look in the library of developed theories which is distributed +with \Coq, in order to acquaint yourself with various proof techniques. + + +\end{document} + +% $Id$ diff --git a/doc/biblio.bib b/doc/biblio.bib new file mode 100755 index 000000000..2e97d1e07 --- /dev/null +++ b/doc/biblio.bib @@ -0,0 +1,895 @@ + +@STRING{toappear="To appear"} +@STRING{lncs="Lecture Notes in Computer Science"} + +@INPROCEEDINGS{Aud91, + AUTHOR = {Ph. Audebaud}, + BOOKTITLE = {Proceedings of the sixth Conf. on Logic in Computer Science.}, + PUBLISHER = {IEEE}, + TITLE = {Partial {Objects} in the {Calculus of Constructions}}, + YEAR = {1991} +} + +@PHDTHESIS{Aud92, + AUTHOR = {Ph. Audebaud}, + SCHOOL = {{Universit\'e} Bordeaux I}, + TITLE = {Extension du Calcul des Constructions par Points fixes}, + YEAR = {1992} +} + +@INPROCEEDINGS{Audebaud92b, + AUTHOR = {Ph. Audebaud}, + BOOKTITLE = {{Proceedings of the 1992 Workshop on Types for Proofs and Programs}}, + EDITOR = {{B. Nordstr\"om and K. Petersson and G. Plotkin}}, + NOTE = {Also Research Report LIP-ENS-Lyon}, + PAGES = {pp 21--34}, + TITLE = {{CC+ : an extension of the Calculus of Constructions with fixpoints}}, + YEAR = {1992} +} + +@INPROCEEDINGS{Augustsson85, + AUTHOR = {L. Augustsson}, + TITLE = {{Compiling Pattern Matching}}, + BOOKTITLE = {Conference Functional Programming and +Computer Architecture}, + YEAR = {1985} +} + +@ARTICLE{BaCo85, + AUTHOR = {J.L. Bates and R.L. Constable}, + JOURNAL = {ACM transactions on Programming Languages and Systems}, + TITLE = {Proofs as {Programs}}, + VOLUME = {7}, + YEAR = {1985} +} + +@BOOK{Bar81, + AUTHOR = {H.P. Barendregt}, + PUBLISHER = {North-Holland}, + TITLE = {The Lambda Calculus its Syntax and Semantics}, + YEAR = {1981} +} + +@TECHREPORT{Bar91, + AUTHOR = {H. Barendregt}, + INSTITUTION = {Catholic University Nijmegen}, + NOTE = {In Handbook of Logic in Computer Science, Vol II}, + NUMBER = {91-19}, + TITLE = {Lambda {Calculi with Types}}, + YEAR = {1991} +} + +@BOOK{Bastad92, + EDITOR = {B. Nordstr\"om and K. Petersson and G. Plotkin}, + PUBLISHER = {Available by ftp at site ftp.inria.fr}, + TITLE = {Proceedings of the 1992 Workshop on Types for Proofs and Programs}, + YEAR = {1992} +} + +@ARTICLE{BeKe92, + AUTHOR = {G. Bellin and J. Ketonen}, + JOURNAL = {Theoretical Computer Science}, + PAGES = {115--142}, + TITLE = {A decision procedure revisited : Notes on direct logic, linear logic and its implementation}, + VOLUME = {95}, + YEAR = {1992} +} + +@BOOK{Bee85, + AUTHOR = {M.J. Beeson}, + PUBLISHER = {Springer-Verlag}, + TITLE = {Foundations of Constructive Mathematics, Metamathematical Studies}, + YEAR = {1985} +} + +@BOOK{Bis67, + AUTHOR = {E. Bishop}, + PUBLISHER = {McGraw-Hill}, + TITLE = {Foundations of Constructive Analysis}, + YEAR = {1967} +} + +@BOOK{BoMo79, + AUTHOR = {R.S. Boyer and J.S. Moore}, + KEY = {BoMo79}, + PUBLISHER = {Academic Press}, + SERIES = {ACM Monograph}, + TITLE = {A computational logic}, + YEAR = {1979} +} + +@MASTERSTHESIS{Bou92, + AUTHOR = {S. Boutin}, + MONTH = sep, + SCHOOL = {{Universit\'e Paris 7}}, + TITLE = {Certification d'un compilateur {ML en Coq}}, + YEAR = {1992} +} + +@inproceedings{Bou97, + title = {Using reflection to build efficient and certified decision procedure +s}, + author = {S. Boutin}, + booktitle = {TACS'97}, + editor = {Martin Abadi and Takahashi Ito}, + publisher = {LNCS, Springer-Verlag}, + volume=1281, + PS={http://pauillac.inria.fr/~boutin/public_w/submitTACS97.ps.gz}, + year = {1997} +} + +@PhdThesis{Bou97These, + author = {S. Boutin}, + title = {Réflexions sur les quotients}, + school = {Paris 7}, + year = 1997, + type = {thèse d'Université}, + month = apr +} + +@ARTICLE{Bru72, + AUTHOR = {N.J. de Bruijn}, + JOURNAL = {Indag. Math.}, + TITLE = {{Lambda-Calculus Notation with Nameless Dummies, a Tool for Automatic Formula Manipulation, with Application to the Church-Rosser Theorem}}, + VOLUME = {34}, + YEAR = {1972} +} + + +@INCOLLECTION{Bru80, + AUTHOR = {N.J. de Bruijn}, + BOOKTITLE = {to H.B. Curry : Essays on Combinatory Logic, Lambda Calculus and Formalism.}, + EDITOR = {J.P. Seldin and J.R. Hindley}, + PUBLISHER = {Academic Press}, + TITLE = {A survey of the project {Automath}}, + YEAR = {1980} +} + +@TECHREPORT{COQ93, + AUTHOR = {G. Dowek and A. Felty and H. Herbelin and G. Huet and C. Murthy and C. Parent and C. Paulin-Mohring and B. Werner}, + INSTITUTION = {INRIA}, + MONTH = may, + NUMBER = {154}, + TITLE = {{The Coq Proof Assistant User's Guide Version 5.8}}, + YEAR = {1993} +} + +@TECHREPORT{CPar93, + AUTHOR = {C. Parent}, + INSTITUTION = {Ecole {Normale} {Sup\'erieure} de {Lyon}}, + MONTH = oct, + NOTE = {Also in~\cite{Nijmegen93}}, + NUMBER = {93-29}, + TITLE = {Developing certified programs in the system {Coq}- {The} {Program} tactic}, + YEAR = {1993} +} + +@PHDTHESIS{CPar95, + AUTHOR = {C. Parent}, + SCHOOL = {Ecole {Normale} {Sup{\'e}rieure} de {Lyon}}, + TITLE = {{Synth\`ese de preuves de programmes dans le Calcul des Constructions Inductives}}, + YEAR = {1995} +} + +@BOOK{Caml, + AUTHOR = {P. Weis and X. Leroy}, + PUBLISHER = {InterEditions}, + TITLE = {Le langage Caml}, + YEAR = {1993} +} + +@TECHREPORT{CoC89, + AUTHOR = {Projet Formel}, + INSTITUTION = {INRIA}, + NUMBER = {110}, + TITLE = {{The Calculus of Constructions. Documentation and user's guide, Version 4.10}}, + YEAR = {1989} +} + +@INPROCEEDINGS{CoHu85a, + AUTHOR = {Th. Coquand and G. Huet}, + ADDRESS = {Linz}, + BOOKTITLE = {EUROCAL'85}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {{Constructions : A Higher Order Proof System for Mechanizing Mathematics}}, + VOLUME = {203}, + YEAR = {1985} +} + +@INPROCEEDINGS{CoHu85b, + AUTHOR = {Th. Coquand and G. Huet}, + BOOKTITLE = {Logic Colloquium'85}, + EDITOR = {The Paris Logic Group}, + PUBLISHER = {North-Holland}, + TITLE = {{Concepts Math\'ematiques et Informatiques formalis\'es dans le Calcul des Constructions}}, + YEAR = {1987} +} + +@ARTICLE{CoHu86, + AUTHOR = {Th. Coquand and G. Huet}, + JOURNAL = {Information and Computation}, + NUMBER = {2/3}, + TITLE = {The {Calculus of Constructions}}, + VOLUME = {76}, + YEAR = {1988} +} + +@INPROCEEDINGS{CoPa89, + AUTHOR = {Th. Coquand and C. Paulin-Mohring}, + BOOKTITLE = {Proceedings of Colog'88}, + EDITOR = {P. Martin-L{\"o}f and G. Mints}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {Inductively defined types}, + VOLUME = {417}, + YEAR = {1990} +} + +@BOOK{Con86, + AUTHOR = {R.L. {Constable et al.}}, + PUBLISHER = {Prentice-Hall}, + TITLE = {{Implementing Mathematics with the Nuprl Proof Development System}}, + YEAR = {1986} +} + +@PHDTHESIS{Coq85, + AUTHOR = {Th. Coquand}, + MONTH = jan, + SCHOOL = {Universit\'e Paris~7}, + TITLE = {Une Th\'eorie des Constructions}, + YEAR = {1985} +} + +@INPROCEEDINGS{Coq86, + AUTHOR = {Th. Coquand}, + ADDRESS = {Cambridge, MA}, + BOOKTITLE = {Symposium on Logic in Computer Science}, + PUBLISHER = {IEEE Computer Society Press}, + TITLE = {{An Analysis of Girard's Paradox}}, + YEAR = {1986} +} + +@INPROCEEDINGS{Coq90, + AUTHOR = {Th. Coquand}, + BOOKTITLE = {Logic and Computer Science}, + EDITOR = {P. Oddifredi}, + NOTE = {INRIA Research Report 1088, also in~\cite{CoC89}}, + PUBLISHER = {Academic Press}, + TITLE = {{Metamathematical Investigations of a Calculus of Constructions}}, + YEAR = {1990} +} + +@INPROCEEDINGS{Coq92, + AUTHOR = {Th. Coquand}, + BOOKTITLE = {in \cite{Bastad92}}, + TITLE = {{Pattern Matching with Dependent Types}}, + YEAR = {1992}, + crossref = {Bastad92} +} + +@INPROCEEDINGS{Coquand93, + AUTHOR = {Th. Coquand}, + BOOKTITLE = {in \cite{Nijmegen93}}, + TITLE = {{Infinite Objects in Type Theory}}, + YEAR = {1993}, + crossref = {Nijmegen93} +} + +@MASTERSTHESIS{Cou94a, + AUTHOR = {J. Courant}, + MONTH = sep, + SCHOOL = {DEA d'Informatique, ENS Lyon}, + TITLE = {Explicitation de preuves par r{\'e}currence implicite}, + YEAR = {1994} +} + +@MASTERSTHESIS{Del97, + AUTHOR = {D. Delahaye}, + MONTH = sep, + SCHOOL = {DEA S{\'e}mantique, Preuves et Programmation, Paris 6}, + TITLE = {Search2: un outil de recherche dans une biblioth\`eque de preuves Coq modulo isomorphismes}, + YEAR = {1997} +} + +@TECHREPORT{Dow90, + AUTHOR = {G. Dowek}, + INSTITUTION = {INRIA}, + NUMBER = {1283}, + TITLE = {{Naming and Scoping in a Mathematical Vernacular}}, + TYPE = {Research Report}, + YEAR = {1990} +} + +@ARTICLE{Dow91a, + AUTHOR = {G. Dowek}, + JOURNAL = {{Compte Rendu de l'Acad\'emie des Sciences}}, + NOTE = {(The undecidability of Third Order Pattern Matching in Calculi with Dependent Types or Type Constructors)}, + NUMBER = {12}, + PAGES = {951--956}, + TITLE = {{L'Ind\'ecidabilit\'e du Filtrage du Troisi\`eme Ordre dans les Calculs avec Types D\'ependants ou Constructeurs de Types}}, + VOLUME = {I, 312}, + YEAR = {1991} +} + +@INPROCEEDINGS{Dow91b, + AUTHOR = {G. Dowek}, + BOOKTITLE = {Proceedings of Mathematical Foundation of Computer Science}, + NOTE = {Also INRIA Research Report}, + PAGES = {151--160}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {{A Second Order Pattern Matching Algorithm in the Cube of Typed {$\lambda$}-calculi}}, + VOLUME = {520}, + YEAR = {1991} +} + +@PHDTHESIS{Dow91c, + AUTHOR = {G. Dowek}, + MONTH = dec, + SCHOOL = {{Universit\'e Paris 7}}, + TITLE = {{D\'emonstration automatique dans le Calcul des Constructions}}, + YEAR = {1991} +} + +@UNPUBLISHED{Dow92a, + AUTHOR = {G. Dowek}, + NOTE = {To appear in Theoretical Computer Science}, + TITLE = {{The Undecidability of Pattern Matching in Calculi where Primitive Recursive Functions are Representable}}, + YEAR = {1992} +} + +@ARTICLE{Dow94a, + AUTHOR = {G. Dowek}, + JOURNAL = {Annals of Pure and Applied Logic}, + VOLUME = {69}, + PAGES = {135--155}, + TITLE = {Third order matching is decidable}, + YEAR = {1994} +} + +@INPROCEEDINGS{Dow94b, + AUTHOR = {G. Dowek}, + BOOKTITLE = {Proceedings of the second international conference on typed lambda calculus and applications}, + TITLE = {{Lambda-calculus, Combinators and the Comprehension Schema}}, + YEAR = {1995} +} + +@INPROCEEDINGS{Dyb91, + AUTHOR = {P. Dybjer}, + BOOKTITLE = {Logical Frameworks}, + EDITOR = {G. Huet and G. Plotkin}, + PAGES = {59--79}, + PUBLISHER = {Cambridge University Press}, + TITLE = {{Inductive sets and families in {Martin-L{\"o}f's Type Theory} and their set-theoretic semantics : An inversion principle for {Martin-L\"of's} type theory}}, + VOLUME = {14}, + YEAR = {1991} +} + +@ARTICLE{Dyc92, + AUTHOR = {Roy Dyckhoff}, + JOURNAL = {The Journal of Symbolic Logic}, + MONTH = sep, + NUMBER = {3}, + TITLE = {Contraction-free sequent calculi for intuitionistic logic}, + VOLUME = {57}, + YEAR = {1992} +} + +@MASTERSTHESIS{Fil94, + AUTHOR = {J.-C. Filli\^atre}, + MONTH = sep, + SCHOOL = {DEA d'Informatique, ENS Lyon}, + TITLE = {Une proc\'edure de d\'ecision pour le {C}alcul des {P}r\'edicats {D}irect. {E}tude et impl\'ementation dans le syst\`eme {C}oq}, + YEAR = {1994} +} + +@TECHREPORT{Filliatre95, + AUTHOR = {J.-C. Filli\^atre}, + INSTITUTION = {LIP-ENS-Lyon}, + TITLE = {{A decision procedure for Direct Predicate Calculus}}, + TYPE = {Research report}, + NUMBER = {96--25}, + YEAR = {1995} +} + +@UNPUBLISHED{Fle90, + AUTHOR = {E. Fleury}, + MONTH = jul, + NOTE = {Rapport de Stage}, + TITLE = {Implantation des algorithmes de {Floyd et de Dijkstra} dans le {Calcul des Constructions}}, + YEAR = {1990} +} + +@INPROCEEDINGS{Gim94, + AUTHOR = {E. Gim\'enez}, + BOOKTITLE = {Types'94 : Types for Proofs and Programs}, + NOTE = {Extended version in LIP research report 95-07, ENS Lyon}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {{Codifying guarded definitions with recursive schemes}}, + VOLUME = {996}, + YEAR = {1994} +} + +@TechReport{Gim98, + author = {E. Giménez}, + title = {A Tutorial on Recursive Types in Coq}, + institution = {INRIA}, + year = 1998, + month = mar +} + +@INPROCEEDINGS{Gimenez95b, + AUTHOR = {E. Gim\'enez}, + BOOKTITLE = {Workshop on Types for Proofs and Programs}, + SERIES = {LNCS}, + NUMBER = {1158}, + PAGES = {135-152}, + TITLE = {An application of co-Inductive types in Coq: + verification of the Alternating Bit Protocol}, + EDITORS = {S. Berardi and M. Coppo}, + PUBLISHER = {Springer-Verlag}, + YEAR = {1995} +} + +@INPROCEEDINGS{Gir70, + AUTHOR = {J.-Y. Girard}, + BOOKTITLE = {Proceedings of the 2nd Scandinavian Logic Symposium}, + PUBLISHER = {North-Holland}, + TITLE = {Une extension de l'interpr\'etation de {G\"odel} \`a l'analyse, et son application \`a l'\'elimination des coupures dans l'analyse et la th\'eorie des types}, + YEAR = {1970} +} + +@PHDTHESIS{Gir72, + AUTHOR = {J.-Y. Girard}, + SCHOOL = {Universit\'e Paris~7}, + TITLE = {Interpr\'etation fonctionnelle et \'elimination des coupures de l'arithm\'etique d'ordre sup\'erieur}, + YEAR = {1972} +} + + + +@BOOK{Gir89, + AUTHOR = {J.-Y. Girard and Y. Lafont and P. Taylor}, + PUBLISHER = {Cambridge University Press}, + SERIES = {Cambridge Tracts in Theoretical Computer Science 7}, + TITLE = {Proofs and Types}, + YEAR = {1989} +} + +@TechReport{Har95, + author = {John Harrison}, + title = {Metatheory and Reflection in Theorem Proving: A Survey and Critique}, + institution = {SRI International Cambridge Computer Science Research Centre,}, + year = 1995, + type = {Technical Report}, + number = {CRC-053}, + abstract = {http://www.cl.cam.ac.uk/users/jrh/papers.html} +} + +@MASTERSTHESIS{Hir94, + AUTHOR = {D. Hirschkoff}, + MONTH = sep, + SCHOOL = {DEA IARFA, Ecole des Ponts et Chauss\'ees, Paris}, + TITLE = {{Ecriture d'une tactique arithm\'etique pour le syst\`eme Coq}}, + YEAR = {1994} +} + +@INCOLLECTION{How80, + AUTHOR = {W.A. Howard}, + BOOKTITLE = {to H.B. Curry : Essays on Combinatory Logic, Lambda Calculus and Formalism.}, + EDITOR = {J.P. Seldin and J.R. Hindley}, + NOTE = {Unpublished 1969 Manuscript}, + PUBLISHER = {Academic Press}, + TITLE = {The Formulae-as-Types Notion of Constructions}, + YEAR = {1980} +} + + + +@INPROCEEDINGS{Hue87, + AUTHOR = {G. Huet}, + BOOKTITLE = {Programming of Future Generation Computers}, + EDITOR = {K. Fuchi and M. Nivat}, + NOTE = {Also in Proceedings of TAPSOFT87, LNCS 249, Springer-Verlag, 1987, pp 276--286}, + PUBLISHER = {Elsevier Science}, + TITLE = {Induction Principles Formalized in the {Calculus of Constructions}}, + YEAR = {1988} +} + +@INPROCEEDINGS{Hue88, + AUTHOR = {G. Huet}, + BOOKTITLE = {A perspective in Theoretical Computer Science. Commemorative Volume for Gift Siromoney}, + EDITOR = {R. Narasimhan}, + NOTE = {Also in~\cite{CoC89}}, + PUBLISHER = {World Scientific Publishing}, + TITLE = {{The Constructive Engine}}, + YEAR = {1989} +} + +@BOOK{Hue89, + EDITOR = {G. Huet}, + PUBLISHER = {Addison-Wesley}, + SERIES = {The UT Year of Programming Series}, + TITLE = {Logical Foundations of Functional Programming}, + YEAR = {1989} +} + +@INPROCEEDINGS{Hue92, + AUTHOR = {G. Huet}, + BOOKTITLE = {Proceedings of 12th FST/TCS Conference, New Delhi}, + PAGES = {229--240}, + PUBLISHER = {Springer Verlag}, + SERIES = {LNCS}, + TITLE = {{The Gallina Specification Language : A case study}}, + VOLUME = {652}, + YEAR = {1992} +} + +@ARTICLE{Hue94, + AUTHOR = {G. Huet}, + JOURNAL = {J. Functional Programming}, + PAGES = {371--394}, + PUBLISHER = {Cambridge University Press}, + TITLE = {Residual theory in $\lambda$-calculus: a formal development}, + VOLUME = {4,3}, + YEAR = {1994} +} + +@INCOLLECTION{HuetLevy79, + AUTHOR = {G. Huet and J.-J. L\'{e}vy}, + TITLE = {Call by Need Computations in Non-Ambigous +Linear Term Rewriting Systems}, + NOTE = {Also research report 359, INRIA, 1979}, + BOOKTITLE = {Computational Logic, Essays in Honor of +Alan Robinson}, + EDITOR = {J.-L. Lassez and G. Plotkin}, + PUBLISHER = {The MIT press}, + YEAR = {1991} +} + +@ARTICLE{KeWe84, + AUTHOR = {J. Ketonen and R. Weyhrauch}, + JOURNAL = {Theoretical Computer Science}, + PAGES = {297--307}, + TITLE = {A decidable fragment of {P}redicate {C}alculus}, + VOLUME = {32}, + YEAR = {1984} +} + +@BOOK{Kle52, + AUTHOR = {S.C. Kleene}, + PUBLISHER = {North-Holland}, + SERIES = {Bibliotheca Mathematica}, + TITLE = {Introduction to Metamathematics}, + YEAR = {1952} +} + +@BOOK{Kri90, + AUTHOR = {J.-L. Krivine}, + PUBLISHER = {Masson}, + SERIES = {Etudes et recherche en informatique}, + TITLE = {Lambda-calcul {types et mod\`eles}}, + YEAR = {1990} +} + +@BOOK{LE92, + EDITOR = {G. Huet and G. Plotkin}, + PUBLISHER = {Cambridge University Press}, + TITLE = {Logical Environments}, + YEAR = {1992} +} + +@BOOK{LF91, + EDITOR = {G. Huet and G. Plotkin}, + PUBLISHER = {Cambridge University Press}, + TITLE = {Logical Frameworks}, + YEAR = {1991} +} + +@ARTICLE{Laville91, + AUTHOR = {A. Laville}, + TITLE = {Comparison of Priority Rules in Pattern +Matching and Term Rewriting}, + JOURNAL = {Journal of Symbolic Computation}, + VOLUME = {11}, + PAGES = {321--347}, + YEAR = {1991} +} + +@INPROCEEDINGS{LePa94, + AUTHOR = {F. Leclerc and C. Paulin-Mohring}, + BOOKTITLE = {{Types for Proofs and Programs, Types' 93}}, + EDITOR = {H. Barendregt and T. Nipkow}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {{Programming with Streams in Coq. A case study : The Sieve of Eratosthenes}}, + VOLUME = {806}, + YEAR = {1994} +} + +@TECHREPORT{Leroy90, + AUTHOR = {X. Leroy}, + TITLE = {The {ZINC} experiment: an economical implementation +of the {ML} language}, + INSTITUTION = {INRIA}, + NUMBER = {117}, + YEAR = {1990} +} + +@BOOK{MaL84, + AUTHOR = {{P. Martin-L\"of}}, + PUBLISHER = {Bibliopolis}, + SERIES = {Studies in Proof Theory}, + TITLE = {Intuitionistic Type Theory}, + YEAR = {1984} +} + +@ARTICLE{MaSi94, + AUTHOR = {P. Manoury and M. Simonot}, + JOURNAL = {TCS}, + TITLE = {Automatizing termination proof of recursively defined function}, + YEAR = {To appear} +} + +@INPROCEEDINGS{Moh89a, + AUTHOR = {C. Paulin-Mohring}, + ADDRESS = {Austin}, + BOOKTITLE = {Sixteenth Annual ACM Symposium on Principles of Programming Languages}, + MONTH = jan, + PUBLISHER = {ACM}, + TITLE = {Extracting ${F}_{\omega}$'s programs from proofs in the {Calculus of Constructions}}, + YEAR = {1989} +} + +@PHDTHESIS{Moh89b, + AUTHOR = {C. Paulin-Mohring}, + MONTH = jan, + SCHOOL = {{Universit\'e Paris 7}}, + TITLE = {Extraction de programmes dans le {Calcul des Constructions}}, + YEAR = {1989} +} + +@INPROCEEDINGS{Moh93, + AUTHOR = {C. Paulin-Mohring}, + BOOKTITLE = {Proceedings of the conference Typed Lambda Calculi and Applications}, + EDITOR = {M. Bezem and J.-F. Groote}, + NOTE = {Also LIP research report 92-49, ENS Lyon}, + NUMBER = {664}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {{Inductive Definitions in the System Coq - Rules and Properties}}, + YEAR = {1993} +} + +@BOOK{Moh97, + AUTHOR = {C. Paulin-Mohring}, + MONTH = jan, + PUBLISHER = {{ENS Lyon}}, + TITLE = {{Le syst\`eme Coq. \mbox{Th\`ese d'habilitation}}}, + YEAR = {1997} +} + +@MASTERSTHESIS{Mun94, + AUTHOR = {C. Mu{\~n}oz}, + MONTH = sep, + SCHOOL = {DEA d'Informatique Fondamentale, Universit\'e Paris 7}, + TITLE = {D\'emonstration automatique dans la logique propositionnelle intuitionniste}, + YEAR = {1994} +} + +@PHDTHESIS{Mun97d, + AUTHOR = "C. Mu{\~{n}}oz", + TITLE = "Un calcul de substitutions pour la repr\'esentation + de preuves partielles en th\'eorie de types", + SCHOOL = {Universit\'e Paris 7}, + YEAR = "1997", + Note = {Version en anglais disponible comme rapport de + recherche INRIA RR-3309}, + Type = {Th\`ese de Doctorat} +} + +@BOOK{Nijmegen93, + EDITOR = {H. Barendregt and T. Nipkow}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {Types for Proofs and Programs}, + VOLUME = {806}, + YEAR = {1994} +} + +@BOOK{NoPS90, + AUTHOR = {B. {Nordstr\"om} and K. Peterson and J. Smith}, + BOOKTITLE = {Information Processing 83}, + PUBLISHER = {Oxford Science Publications}, + SERIES = {International Series of Monographs on Computer Science}, + TITLE = {Programming in {Martin-L\"of's} Type Theory}, + YEAR = {1990} +} + +@ARTICLE{Nor88, + AUTHOR = {B. {Nordstr\"om}}, + JOURNAL = {BIT}, + TITLE = {Terminating General Recursion}, + VOLUME = {28}, + YEAR = {1988} +} + +@BOOK{Odi90, + EDITOR = {P. Odifreddi}, + PUBLISHER = {Academic Press}, + TITLE = {Logic and Computer Science}, + YEAR = {1990} +} + +@INPROCEEDINGS{PaMS92, + AUTHOR = {M. Parigot and P. Manoury and M. Simonot}, + ADDRESS = {St. Petersburg, Russia}, + BOOKTITLE = {Logic Programming and automated reasoning}, + EDITOR = {A. Voronkov}, + MONTH = jul, + NUMBER = {624}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {{ProPre : A Programming language with proofs}}, + YEAR = {1992} +} + +@ARTICLE{PaWe92, + AUTHOR = {C. Paulin-Mohring and B. Werner}, + JOURNAL = {Journal of Symbolic Computation}, + PAGES = {607--640}, + TITLE = {{Synthesis of ML programs in the system Coq}}, + VOLUME = {15}, + YEAR = {1993} +} + +@ARTICLE{Par92, + AUTHOR = {M. Parigot}, + JOURNAL = {Theoretical Computer Science}, + NUMBER = {2}, + PAGES = {335--356}, + TITLE = {{Recursive Programming with Proofs}}, + VOLUME = {94}, + YEAR = {1992} +} + +@INPROCEEDINGS{Parent95b, + AUTHOR = {C. Parent}, + BOOKTITLE = {{Mathematics of Program Construction'95}}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {{Synthesizing proofs from programs in +the Calculus of Inductive Constructions}}, + VOLUME = {947}, + YEAR = {1995} +} + +@INPROCEEDINGS{Prasad93, + AUTHOR = {K.V. Prasad}, + BOOKTITLE = {{Proceedings of CONCUR'93}}, + PUBLISHER = {Springer-Verlag}, + SERIES = {LNCS}, + TITLE = {{Programming with broadcasts}}, + VOLUME = {715}, + YEAR = {1993} +} + +@TECHREPORT{Rou92, + AUTHOR = {J. Rouyer}, + INSTITUTION = {INRIA}, + MONTH = nov, + NUMBER = {1795}, + TITLE = {{D{\'e}veloppement de l'Algorithme d'Unification dans le Calcul des Constructions}}, + YEAR = {1992} +} + +@TECHREPORT{Saibi94, + AUTHOR = {A. Sa\"{\i}bi}, + INSTITUTION = {INRIA}, + MONTH = dec, + NUMBER = {2345}, + TITLE = {{Axiomatization of a lambda-calculus with explicit-substitutions in the Coq System}}, + YEAR = {1994} +} + +@MASTERSTHESIS{Ter92, + AUTHOR = {D. Terrasse}, + MONTH = sep, + SCHOOL = {IARFA}, + TITLE = {{Traduction de TYPOL en COQ. Application \`a Mini ML}}, + YEAR = {1992} +} + +@TECHREPORT{ThBeKa92, + AUTHOR = {L. Th\'ery and Y. Bertot and G. Kahn}, + INSTITUTION = {INRIA Sophia}, + MONTH = may, + NUMBER = {1684}, + TITLE = {Real theorem provers deserve real user-interfaces}, + TYPE = {Research Report}, + YEAR = {1992} +} + +@BOOK{TrDa89, + AUTHOR = {A.S. Troelstra and D. van Dalen}, + PUBLISHER = {North-Holland}, + SERIES = {Studies in Logic and the foundations of Mathematics, volumes 121 and 123}, + TITLE = {Constructivism in Mathematics, an introduction}, + YEAR = {1988} +} + +@PHDTHESIS{Wer94, + AUTHOR = {B. Werner}, + SCHOOL = {Universit\'e Paris 7}, + TITLE = {Une th\'eorie des constructions inductives}, + TYPE = {Th\`ese de Doctorat}, + YEAR = {1994} +} + +@UNPUBLISHED{ddr98, + AUTHOR = {D. de Rauglaudre}, + TITLE = {Camlp4 version 1.07.2}, + YEAR = {1998}, + NOTE = {In Camlp4 distribution} +} + +@ARTICLE{dowek93, + AUTHOR = {G. Dowek}, + TITLE = {{A Complete Proof Synthesis Method for the Cube of Type Systems}}, + JOURNAL = {Journal Logic Computation}, + VOLUME = {3}, + NUMBER = {3}, + PAGES = {287--315}, + MONTH = {June}, + YEAR = {1993} +} + +@INPROCEEDINGS{manoury94, + AUTHOR = {P. Manoury}, + TITLE = {{A User's Friendly Syntax to Define +Recursive Functions as Typed $\lambda-$Terms}}, + BOOKTITLE = {{Types for Proofs and Programs, TYPES'94}}, + SERIES = {LNCS}, + VOLUME = {996}, + MONTH = jun, + YEAR = {1994} +} + +@TECHREPORT{maranget94, + AUTHOR = {L. Maranget}, + INSTITUTION = {INRIA}, + NUMBER = {2385}, + TITLE = {{Two Techniques for Compiling Lazy Pattern Matching}}, + YEAR = {1994} +} + +@INPROCEEDINGS{puel-suarez90, + AUTHOR = {L.Puel and A. Su\'arez}, + BOOKTITLE = {{Conference Lisp and Functional Programming}}, + SERIES = {ACM}, + PUBLISHER = {Springer-Verlag}, + TITLE = {{Compiling Pattern Matching by Term +Decomposition}}, + YEAR = {1990} +} + +@MASTERSTHESIS{saidi94, + AUTHOR = {H. Saidi}, + MONTH = sep, + SCHOOL = {DEA d'Informatique Fondamentale, Universit\'e Paris 7}, + TITLE = {R\'esolution d'\'equations dans le syst\`eme T + de G\"odel}, + YEAR = {1994} +} + +@INCOLLECTION{wadler87, + AUTHOR = {P. Wadler}, + TITLE = {Efficient Compilation of Pattern Matching}, + BOOKTITLE = {The Implementation of Functional Programming +Languages}, + EDITOR = {S.L. Peyton Jones}, + PUBLISHER = {Prentice-Hall}, + YEAR = {1987} +} diff --git a/doc/book-html.sty b/doc/book-html.sty new file mode 100644 index 000000000..0592e622d --- /dev/null +++ b/doc/book-html.sty @@ -0,0 +1,133 @@ +\newcounter {part} +\newcounter {chapter} +\newcounter {section}[chapter] +\newcounter {subsection}[section] +\newcounter {subsubsection}[subsection] +\newcounter {paragraph}[subsubsection] +\newcounter {subparagraph}[paragraph] +\renewcommand \thepart {\Roman{part}} +\renewcommand \thesection {\thechapter.\arabic{section}} +\renewcommand\thesubsection {\thesection.\arabic{subsection}} +\renewcommand\thesubsubsection{\thesubsection .\arabic{subsubsection}} +\renewcommand\theparagraph {\thesubsubsection.\arabic{paragraph}} +\renewcommand\thesubparagraph {\theparagraph.\arabic{subparagraph}} +\newcommand{\partname}{Part} +\newcommand{\chaptername}{Chapter} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\newcommand{\appendix}{% +\renewcommand{\chaptername}{Appendix}% +\setcounter{chapter}{0}% +\renewcommand{\thechapter}{\Alph{chapter}}% +} +\newcounter{figure}[chapter] +\renewcommand{\thefigure}{\thechapter.\arabic{figure}} + +\newcommand{\part}[1]{% +\@print{<!--CUT PART-->} +\@open{H1}{ALIGN=center} +\stepcounter{part} +\partname:~\thepart\\ +#1 +\@close{H1} +} +\newcommand{\part*}[1]{% +\@print{<!--CUT CHAPTER-->} +\@open{H1}{ALIGN=center} +#1 +\@close{H1} +} + +\newcommand{\chapter}[1]{% +\@print{<!--CUT CHAPTER-->} +\@open{H1}{} +\stepcounter{chapter} +\chaptername~\thechapter: #1 +\@close{H1} +} +\newcommand{\chapter*}[1]{% +\@print{<!--CUT CHAPTER-->} +\@open{H1}{} +#1 +\@close{H1} +} + +\newcommand{\section}[1]{% +\@print{<!--CUT SECTION-->} +\@open{H2}{} +\stepcounter{section} +\thesection~#1 +\@close{H2} +} +\newcommand{\section*}[1]{% +\@print{<!--CUT SECTION-->} +\@open{H2}{} +#1 +\@close{H2} +} + + +\newcommand{\subsection}[1]{% +\@open{H3}{} +\stepcounter{subsection} +\thesubsection~#1 +\@close{H3} +} +\newcommand{\subsection*}[1]{% +\@open{H3}{} +#1 +\@close{H3} +} + + +\newcommand{\subsubsection}[1]{% +\@open{H4}{} +% \stepcounter{subsubsection} +% \thesubsubsection~ +#1 +\@close{H4} +} +\newcommand{\subsubsection*}[1]{% +\@open{H4}{} +#1 +\@close{H4} +} + +\newcommand{\paragraph}[1]{% +\@open{H5}{} +% \stepcounter{paragraph} +% \theparagraph~ +#1 +\@close{H5} +} +\newcommand{\paragraph*}[1]{% +\@open{H5}{} +#1 +\@close{H5} +} + +\renewenvironment{thebibliography}[1]{% +\@print{ +<!--CUT BIBLIOGRAPHY--> +} +\@open{H1}{} +\bibname\@close{H1}\@open{DL}{}}{% + +\@close{DL} +} +\renewcommand{\bibitem}[1]{\item[{\purple[\@bibref{#1}]\label{#1}}]} +\renewcommand{\index}[2][default]{\@index[#1]{#2}} +\renewcommand{\printindex}[1][default]{% +\@print{ +<!--CUT INDEX--> +} +\@printindex[#1] +} + +\renewcommand{\addtocontents}[2]{} + +\newcommand{\tophtml}{% +\@print{ +<!--CUT TOP--> +}} + +\newcommand{\atableofcontents}{} diff --git a/doc/coq-html.sty b/doc/coq-html.sty new file mode 100644 index 000000000..2793fdc2a --- /dev/null +++ b/doc/coq-html.sty @@ -0,0 +1,6 @@ +\def\sf{\purple} +\def\textsf#1{{\sf #1}} +\newcommand{\inference}[1]{$${#1}$$} +\newcommand{\NInd}[3]{\mbox{{\sf Ind}$(#1)(#2:=#3\,)$}} +\newcommand{\Ind}[4]{\mbox{{\sf Ind}$(#1)[#2](#3:=#4\,)$}} +\renewcommand{\medskip}{\\} diff --git a/doc/headers.tex b/doc/headers.tex new file mode 100644 index 000000000..11664861f --- /dev/null +++ b/doc/headers.tex @@ -0,0 +1,86 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% File title.tex +% Pretty Headers +% And commands for multiple indexes +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\usepackage{fancyhdr} + +\setlength{\headheight}{14pt} + +\pagestyle{fancyplain} + +\newcommand{\coqfooter}{\tiny Coq Reference Manual, V\coqversion{}, \today} + +\cfoot{} +\lfoot[{\coqfooter}]{} +\rfoot[]{{\coqfooter}} + +\newcommand{\setheaders}[1]{ +\rhead[\fancyplain{}{\textbf{#1}}]{\fancyplain{}{\thepage}} +\lhead[\fancyplain{}{\thepage}]{\fancyplain{}{\textbf{#1}}} +} +\newcommand{\defaultheaders}{ +\rhead[\fancyplain{}{\leftmark}]{\fancyplain{}{\thepage}} +\lhead[\fancyplain{}{\thepage}]{\fancyplain{}{\rightmark}} +} + +\renewcommand{\chaptermark}[1]{\markboth{{\bf \thechapter~#1}}{}} +\renewcommand{\sectionmark}[1]{\markright{\thesection~#1}} +\renewcommand{\contentsname}{% +\protect\setheaders{Table of contents}Table of contents} +\renewcommand{\bibname}{\protect\setheaders{Bibliography}% +\protect\addtocontents{sh}{BEGINBIBLIO=\thepage}% +\protect\addcontentsline{toc}{chapter}{Bibliography}Bibliography} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% For the Addendum table of contents +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\newcommand{\atableofcontents}{\section*{Contents}\@starttoc{atoc}} +\newcommand{\aauthor}[1]{{\LARGE \bf #1} \bigskip \bigskip \bigskip} +\newcommand{\achapter}[1]{ + \chapter{#1}\addcontentsline{atoc}{chapter}{#1}} +\newcommand{\asection}[1]{ + \section{#1}\addcontentsline{atoc}{section}{#1}} +\newcommand{\asubsection}[1]{ + \subsection{#1}\addcontentsline{atoc}{subsection}{#1}} +\newcommand{\asubsubsection}[1]{ + \subsubsection{#1}\addcontentsline{atoc}{subsubsection}{#1}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Reference-Manual.sh is generated to cut the Postscript +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\@starttoc{sh} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Commands for indexes +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\usepackage{index} +\makeindex +\newindex{tactic}{tacidx}{tacind}{% +\protect\setheaders{Tactics Index}% +\protect\addcontentsline{toc}{chapter}{Tactics Index}Tactics Index} + +\newindex{command}{comidx}{comind}{% +\protect\setheaders{Vernacular Commands Index}% +\protect\addcontentsline{toc}{chapter}{Vernacular Commands Index}% +Vernacular Commands Index} + +\newindex{error}{erridx}{errind}{% +\protect\setheaders{Index of Error Messages}% +\protect\addcontentsline{toc}{chapter}{Index of Error Messages}Index of Error Messages} + +\renewindex{default}{idx}{ind}{% +\protect\addcontentsline{toc}{chapter}{Global Index}% +\protect\setheaders{Global Index}Global Index} + +\newcommand{\tacindex}[1]{% +\index{#1@\texttt{#1}}\index[tactic]{#1@\texttt{#1}}} +\newcommand{\comindex}[1]{% +\index{#1@\texttt{#1}}\index[command]{#1@\texttt{#1}}} +\newcommand{\errindex}[1]{\texttt{#1}\index[error]{#1}} +\newcommand{\ttindex}[1]{\index{#1@\texttt{#1}}} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/macros.tex b/doc/macros.tex new file mode 100755 index 000000000..3ccfbbddd --- /dev/null +++ b/doc/macros.tex @@ -0,0 +1,334 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% MACROS FOR THE REFERENCE MANUAL OF COQ % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newcommand{\coqversion}{6.3.1} + +% For commentaries (define \com as {} for the release manual) +%\newcommand{\com}[1]{{\it(* #1 *)}} +\newcommand{\com}[1]{} + +%%%%%%%%%%%%%%%%%%%%%%% +% Formatting commands % +%%%%%%%%%%%%%%%%%%%%%%% + +\newcommand{\ErrMsg}{\medskip \noindent {\bf Error message: }} +\newcommand{\ErrMsgx}{\medskip \noindent {\bf Error messages: }} +\newcommand{\variant}{\medskip \noindent {\bf Variant: }} +\newcommand{\variants}{\medskip \noindent {\bf Variants: }} +\newcommand{\SeeAlso}{\medskip \noindent {\bf See also: }} +\newcommand{\Rem}{\medskip \noindent {\bf Remark: }} +\newcommand{\Rems}{\medskip \noindent {\bf Remarks: }} +\newcommand{\Example}{\medskip \noindent {\bf Example: }} +\newcommand{\Warning}{\medskip \noindent {\bf Warning: }} +\newcommand{\Warns}{\medskip \noindent {\bf Warnings: }} +\newcounter{ex} +\newcommand{\firstexample}{\setcounter{ex}{1}} +\newcommand{\example}[1]{ +\medskip \noindent \textbf{Example \arabic{ex}: }\textit{#1} +\addtocounter{ex}{1}} + +\newenvironment{Variant}{\variant\begin{enumerate}}{\end{enumerate}} +\newenvironment{Variants}{\variants\begin{enumerate}}{\end{enumerate}} +\newenvironment{ErrMsgs}{\ErrMsgx\begin{enumerate}}{\end{enumerate}} +\newenvironment{Remarks}{\Rems\begin{enumerate}}{\end{enumerate}} +\newenvironment{Warnings}{\Warns\begin{enumerate}}{\end{enumerate}} +\newenvironment{Examples}{\medskip\noindent{\bf Examples:} +\begin{enumerate}}{\end{enumerate}} + +\newcommand{\rr}{\raggedright} + +\newcommand{\tinyskip}{\rule{0mm}{4mm}} + +\newcommand{\bd}{\noindent\bf} +\newcommand{\sbd}{\vspace{8pt}\noindent\bf} +\newcommand{\sdoll}[1]{\begin{small}$ #1~ $\end{small}} +\newcommand{\sdollnb}[1]{\begin{small}$ #1 $\end{small}} +\newcommand{\kw}[1]{\textsf{#1}} +\newcommand{\spec}[1]{\{\,#1\,\}} + +% Building regular expressions +\newcommand{\zeroone}[1]{{\sl [}#1{\sl ]}} +%\newcommand{\zeroonemany}[1]{$\{$#1$\}$*} +%\newcommand{\onemany}[1]{$\{$#1$\}$+} +\newcommand{\nelist}[2]{{#1} {\tt #2} {\ldots} {\tt #2} {#1}} +\newcommand{\sequence}[2]{{\sl [}{#1} {\tt #2} {\ldots} {\tt #2} {#1}{\sl ]}} +\newcommand{\nelistwithoutblank}[2]{#1{\tt #2}\ldots{\tt #2}#1} +\newcommand{\sequencewithoutblank}[2]{$[$#1{\tt #2}\ldots{\tt #2}#1$]$} + +% Used for RefMan-gal +\newcommand{\ml}[1]{\hbox{\tt{#1}}} +\newcommand{\op}{\,|\,} + +%%%%%%%%%%%%%%%%%%%%%%%% +% Trademarks and so on % +%%%%%%%%%%%%%%%%%%%%%%%% + +\newcommand{\Coq}{{\sf Coq}} +\newcommand{\ocaml}{{\sf Objective Caml}} +\newcommand{\camlpppp}{{\sf Camlp4}} +\newcommand{\emacs}{{\sf GNU Emacs}} +\newcommand{\gallina}{\textsf{Gallina}} +\newcommand{\CIC}{\mbox{\sc Cic}} +\newcommand{\FW}{\mbox{$F_{\omega}$}} + +%%%%%%%%%%%%%%%%%%% +% Name of tactics % +%%%%%%%%%%%%%%%%%%% + +\newcommand{\Natural}{\mbox{\tt Natural}} + +%%%%%%%%%%%%%%%%% +% \rm\sl series % +%%%%%%%%%%%%%%%%% + +\newcommand{\Fwterm}{\textrm{\textsl{Fwterm}}} +\newcommand{\Index}{\textrm{\textsl{index}}} +\newcommand{\abbrev}{\textrm{\textsl{abbreviation}}} +\newcommand{\annotation}{\textrm{\textsl{annotation}}} +\newcommand{\atomictac}{\textrm{\textsl{atomic\_tactic}}} +\newcommand{\binders}{\textrm{\textsl{bindings}}} +\newcommand{\binder}{\textrm{\textsl{binding}}} +\newcommand{\bindinglist}{\textrm{\textsl{bindings\_list}}} +\newcommand{\cast}{\textrm{\textsl{cast}}} +\newcommand{\cofixpointbody}{\textrm{\textsl{cofix\_body}}} +\newcommand{\coinductivebody}{\textrm{\textsl{coind\_body}}} +\newcommand{\commandtac}{\textrm{\textsl{tactic\_invocation}}} +\newcommand{\constructor}{\textrm{\textsl{constructor}}} +\newcommand{\convtactic}{\textrm{\textsl{conv\_tactic}}} +\newcommand{\declarationkeyword}{\textrm{\textsl{declaration\_keyword}}} +\newcommand{\declaration}{\textrm{\textsl{declaration}}} +\newcommand{\definition}{\textrm{\textsl{definition}}} +\newcommand{\digit}{\textrm{\textsl{digit}}} +\newcommand{\eqn}{\textrm{\textsl{equation}}} +\newcommand{\exteqn}{\textrm{\textsl{ext\_eqn}}} +\newcommand{\field}{\textrm{\textsl{field}}} +\newcommand{\firstletter}{\textrm{\textsl{first\_letter}}} +\newcommand{\fixpg}{\textrm{\textsl{fix\_pgm}}} +\newcommand{\fixpointbody}{\textrm{\textsl{fix\_body}}} +\newcommand{\fixpoint}{\textrm{\textsl{fixpoint}}} +\newcommand{\flag}{\textrm{\textsl{flag}}} +\newcommand{\form}{\textrm{\textsl{form}}} +\newcommand{\gensymbol}{\textrm{\textsl{symbol}}} +\newcommand{\idents}{\textrm{\textsl{idents}}} +\newcommand{\ident}{\textrm{\textsl{ident}}} +\newcommand{\inductivebody}{\textrm{\textsl{ind\_body}}} +\newcommand{\inductive}{\textrm{\textsl{inductive}}} +\newcommand{\integer}{\textrm{\textsl{integer}}} +\newcommand{\multpattern}{\textrm{\textsl{mult\_pattern}}} +\newcommand{\mutualcoinductive}{\textrm{\textsl{mutual\_coinductive}}} +\newcommand{\mutualinductive}{\textrm{\textsl{mutual\_inductive}}} +\newcommand{\nestedpattern}{\textrm{\textsl{nested\_pattern}}} +\newcommand{\num}{\textrm{\textsl{num}}} +\newcommand{\params}{\textrm{\textsl{params}}} +\newcommand{\pattern}{\textrm{\textsl{pattern}}} +\newcommand{\pat}{\textrm{\textsl{pat}}} +\newcommand{\pgs}{\textrm{\textsl{pgms}}} +\newcommand{\pg}{\textrm{\textsl{pgm}}} +\newcommand{\proof}{\textrm{\textsl{proof}}} +\newcommand{\record}{\textrm{\textsl{record}}} +\newcommand{\rewrule}{\textrm{\textsl{rewriting\_rule}}} +\newcommand{\sentence}{\textrm{\textsl{sentence}}} +\newcommand{\simplepattern}{\textrm{\textsl{simple\_pattern}}} +\newcommand{\sort}{\textrm{\textsl{sort}}} +\newcommand{\specif}{\textrm{\textsl{specif}}} +\newcommand{\statement}{\textrm{\textsl{statement}}} +\newcommand{\str}{\textrm{\textsl{string}}} +\newcommand{\subsequentletter}{\textrm{\textsl{subsequent\_letter}}} +\newcommand{\switch}{\textrm{\textsl{switch}}} +\newcommand{\tac}{\textrm{\textsl{tactic}}} +\newcommand{\terms}{\textrm{\textsl{terms}}} +\newcommand{\term}{\textrm{\textsl{term}}} +\newcommand{\typedidents}{\textrm{\textsl{typed\_idents}}} +\newcommand{\type}{\textrm{\textsl{type}}} +\newcommand{\vref}{\textrm{\textsl{ref}}} +\newcommand{\zarithformula}{\textrm{\textsl{zarith\_formula}}} +\newcommand{\zarith}{\textrm{\textsl{zarith}}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \mbox{\sf } series for roman text in maths formulas % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newcommand{\alors}{\mbox{\textsf{then}}} +\newcommand{\alter}{\mbox{\textsf{alter}}} +\newcommand{\bool}{\mbox{\textsf{bool}}} +\newcommand{\conc}{\mbox{\textsf{conc}}} +\newcommand{\cons}{\mbox{\textsf{cons}}} +\newcommand{\consf}{\mbox{\textsf{consf}}} +\newcommand{\emptyf}{\mbox{\textsf{emptyf}}} +\newcommand{\EqSt}{\mbox{\textsf{EqSt}}} +\newcommand{\false}{\mbox{\textsf{false}}} +\newcommand{\filter}{\mbox{\textsf{filter}}} +\newcommand{\forest}{\mbox{\textsf{forest}}} +\newcommand{\from}{\mbox{\textsf{from}}} +\newcommand{\hd}{\mbox{\textsf{hd}}} +\newcommand{\Length}{\mbox{\textsf{Length}}} +\newcommand{\length}{\mbox{\textsf{length}}} +\newcommand{\LengthA}{\mbox {\textsf{Length\_A}}} +\newcommand{\List}{\mbox{\textsf{List}}} +\newcommand{\ListA}{\mbox{\textsf{List\_A}}} +\newcommand{\LNil}{\mbox{\textsf{Lnil}}} +\newcommand{\LCons}{\mbox{\textsf{Lcons}}} +\newcommand{\nat}{\mbox{\textsf{nat}}} +\newcommand{\nO}{\mbox{\textsf{O}}} +\newcommand{\nS}{\mbox{\textsf{S}}} +\newcommand{\node}{\mbox{\textsf{node}}} +\newcommand{\Nil}{\mbox{\textsf{nil}}} +\newcommand{\Prop}{\mbox{\textsf{Prop}}} +\newcommand{\Set}{\mbox{\textsf{Set}}} +\newcommand{\si}{\mbox{\textsf{if}}} +\newcommand{\sinon}{\mbox{\textsf{else}}} +\newcommand{\Str}{\mbox{\textsf{Stream}}} +\newcommand{\tl}{\mbox{\textsf{tl}}} +\newcommand{\tree}{\mbox{\textsf{tree}}} +\newcommand{\true}{\mbox{\textsf{true}}} +\newcommand{\Type}{\mbox{\textsf{Type}}} +\newcommand{\unfold}{\mbox{\textsf{unfold}}} +\newcommand{\zeros}{\mbox{\textsf{zeros}}} + +%%%%%%%%% +% Misc. % +%%%%%%%%% +\newcommand{\T}{\texttt{T}} +\newcommand{\U}{\texttt{U}} +\newcommand{\real}{\textsf{Real}} +\newcommand{\Spec}{\textit{Spec}} +\newcommand{\Data}{\textit{Data}} +\newcommand{\In} {{\textbf{in }}} +\newcommand{\AND} {{\textbf{and}}} +\newcommand{\If}{{\textbf{if }}} +\newcommand{\Else}{{\textbf{else }}} +\newcommand{\Then} {{\textbf{then }}} +\newcommand{\Let}{{\textbf{let }}} +\newcommand{\Where}{{\textbf{where rec }}} +\newcommand{\Function}{{\textbf{function }}} +\newcommand{\Rec}{{\textbf{rec }}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Math commands and symbols % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newcommand{\la}{\leftarrow} +\newcommand{\ra}{\rightarrow} +\newcommand{\Ra}{\Rightarrow} +\newcommand{\rt}{\Rightarrow} +\newcommand{\lla}{\longleftarrow} +\newcommand{\lra}{\longrightarrow} +\newcommand{\Llra}{\Longleftrightarrow} +\newcommand{\mt}{\mapsto} +\newcommand{\ov}{\overrightarrow} +\newcommand{\wh}{\widehat} +\newcommand{\up}{\uparrow} +\newcommand{\dw}{\downarrow} +\newcommand{\nr}{\nearrow} +\newcommand{\se}{\searrow} +\newcommand{\sw}{\swarrow} +\newcommand{\nw}{\nwarrow} + +\newcommand{\vm}[1]{\vspace{#1em}} +\newcommand{\vx}[1]{\vspace{#1ex}} +\newcommand{\hm}[1]{\hspace{#1em}} +\newcommand{\hx}[1]{\hspace{#1ex}} +\newcommand{\sm}{\mbox{ }} +\newcommand{\mx}{\mbox} + +\newcommand{\nq}{\neq} +\newcommand{\eq}{\equiv} +\newcommand{\fa}{\forall} +\newcommand{\ex}{\exists} +\newcommand{\impl}{\rightarrow} +\newcommand{\Or}{\vee} +\newcommand{\And}{\wedge} +\newcommand{\ms}{\models} +\newcommand{\bw}{\bigwedge} +\newcommand{\ts}{\times} +\newcommand{\cc}{\circ} +\newcommand{\es}{\emptyset} +\newcommand{\bs}{\backslash} +\newcommand{\vd}{\vdash} +\newcommand{\lan}{{\langle }} +\newcommand{\ran}{{\rangle }} + +\newcommand{\al}{\alpha} +\newcommand{\bt}{\beta} +\newcommand{\io}{\iota} +\newcommand{\lb}{\lambda} +\newcommand{\sg}{\sigma} +\newcommand{\sa}{\Sigma} +\newcommand{\om}{\Omega} +\newcommand{\tu}{\tau} + +%%%%%%%%%%%%%%%%%%%%%%%%% +% Custom maths commands % +%%%%%%%%%%%%%%%%%%%%%%%%% + +\newcommand{\sumbool}[2]{\{#1\}+\{#2\}} +\newcommand{\myifthenelse}[3]{\kw{if} ~ #1 ~\kw{then} ~ #2 ~ \kw{else} ~ #3} +\newcommand{\fun}[2]{\item[]{\tt {#1}}. \quad\\ #2} +\newcommand{\WF}[2]{\mbox{${\cal W\!F}(#1)[#2]$}} +\newcommand{\WFE}[1]{\WF{E}{#1}} +\newcommand{\WT}[4]{\mbox{$#1[#2] \vdash #3 : #4$}} +\newcommand{\WTE}[3]{\WT{E}{#1}{#2}{#3}} +\newcommand{\WTEG}[2]{\WTE{\Gamma}{#1}{#2}} +\newcommand{\CI}[2]{\mbox{$\{#1\}^{#2}$}} +\newcommand{\CIP}[3]{\mbox{$\{#1\}_{#2}^{#3}$}} +\newcommand{\CIPV}[1]{\CIP{#1}{I_1.. I_k}{P_1.. P_k}} +\newcommand{\CIPI}[1]{\CIP{#1}{I}{P}} +\newcommand{\CIF}[1]{\mbox{$\{#1\}_{f_1.. f_n}$}} +\newcommand{\NInd}[3]{\mbox{{\sf Ind}$(#1)(\begin{array}[t]{l}#2:=#3 + \,)\end{array}$}} +\newcommand{\Ind}[4]{\mbox{{\sf Ind}$(#1)[#2](\begin{array}[t]{l}#3:=#4 + \,)\end{array}$}} +\newcommand{\Def}[4]{\mbox{{\sf Def}$(#1)(#2:=#3:#4)$}} +\newcommand{\Match}[3]{\mbox{$<\!#1\!>\!{\mbox{\tt Match}}~#2~{\mbox{\tt with}}~#3~{\mbox{\tt end}}$}} +\newcommand{\Case}[3]{\mbox{$<\!#1\!>\!{\mbox{\tt Cases}}~#2~{\mbox{\tt of}}~#3~{\mbox{\tt end}}$}} +\newcommand{\Fix}[2]{\mbox{\tt Fix}~#1\{#2\}} +\newcommand{\CoFix}[2]{\mbox{\tt CoFix}~#1\{#2\}} +\newcommand{\With}[2]{\mbox{\tt ~with~}} +\newcommand{\subst}[3]{#1\{#2/#3\}} +\newcommand{\substs}[4]{#1\{(#2/#3)_{#4}\}} +\newcommand{\Sort}{\mbox{$\cal S$}} +\newcommand{\convert}{=_{\beta\delta\iota}} +\newcommand{\leconvert}{\leq_{\beta\delta\iota}} +\newcommand{\NN}{\mbox{I\hspace{-7pt}N}} +\newcommand{\inference}[1]{$${#1}$$} +\newcommand{\compat}[2]{\mbox{$[#1|#2]$}} +\newcommand{\tristackrel}[3]{\mathrel{\mathop{#2}\limits_{#3}^{#1}}} + +\newbox\tempa +\newbox\tempb +\newdimen\tempc +\newcommand{\mud}[1]{\hfil $\displaystyle{\mathstrut #1}$\hfil} +\newcommand{\rig}[1]{\hfil $\displaystyle{#1}$} +\newcommand{\irulehelp}[3]{\setbox\tempa=\hbox{$\displaystyle{\mathstrut #2}$}% + \setbox\tempb=\vbox{\halign{##\cr + \mud{#1}\cr + \noalign{\vskip\the\lineskip} + \noalign{\hrule height 0pt} + \rig{\vbox to 0pt{\vss\hbox to 0pt{${\; #3}$\hss}\vss}}\cr + \noalign{\hrule} + \noalign{\vskip\the\lineskip} + \mud{\copy\tempa}\cr}} + \tempc=\wd\tempb + \advance\tempc by \wd\tempa + \divide\tempc by 2 } +\newcommand{\irule}[3]{{\irulehelp{#1}{#2}{#3} + \hbox to \wd\tempa{\hss \box\tempb \hss}}} + +\newcommand{\sverb}[1]{\tt #1} +\newcommand{\mover}[2]{{#1\over #2}} +\newcommand{\jd}[2]{#1 \vdash #2} +\newcommand{\mathline}[1]{\[#1\]} +\newcommand{\zrule}[2]{#2: #1} +\newcommand{\orule}[3]{#3: {\mover{#1}{#2}}} +\newcommand{\trule}[4]{#4: \mover{#1 \qquad #2} {#3}} +\newcommand{\thrule}[5]{#5: {\mover{#1 \qquad #2 \qquad #3}{#4}}} + + +% $Id$ + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "Reference-Manual" +%%% End: diff --git a/doc/title.tex b/doc/title.tex new file mode 100755 index 000000000..816f0fd53 --- /dev/null +++ b/doc/title.tex @@ -0,0 +1,77 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% File title.tex +% Page formatting commands +% Macro \coverpage +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%\setlength{\marginparwidth}{0pt} +%\setlength{\oddsidemargin}{0pt} +%\setlength{\evensidemargin}{0pt} +%\setlength{\marginparsep}{0pt} +%\setlength{\topmargin}{0pt} +%\setlength{\textwidth}{16.9cm} +%\setlength{\textheight}{22cm} +\usepackage{fullpage} + +\newcommand{\printingdate}{\today} +\newcommand{\isdraft}{\Large\bf\today\\[20pt]} +%\newcommand{\isdraft}{\vspace{20pt}} + +%To show the top for the toc in html +\newcommand{\tophtml}{} + +\newcommand{\coverpage}[2]{ +\thispagestyle{empty} +\begin{center} +\begin{Huge} +\begin{bf} +The Coq Proof Assistant\\ +\vspace{12pt} + #1\\ +\end{bf} +\end{Huge} +\vspace{20pt} +\isdraft +{\Large \bf Version \coqversion} +\footnote[1]{This research was partly supported by ESPRIT Basic Research +Action ``Types'' and by the GDR ``Programmation'' co-financed by MRE-PRC and CNRS.}\\ +\vspace{120pt} +{\bf #2}\\ +\vfill +{\Large \bf Coq Project}\\ +\vspace{15pt} +\end{center} + +\newpage +\vspace*{520pt} +\thispagestyle{empty} +\begin{flushleft} +{\large{V6.3.1, +\printingdate}}\\[20pt] +{\large{\copyright INRIA 1999}}\\ +\end{flushleft} +\newpage} + +\newcommand{\shorttitle}[1]{ +\begin{center} +\begin{huge} +\begin{bf} +The Coq Proof Assistant\\ +\vspace{10pt} + #1\\ +\end{bf} +\end{huge} +\end{center} +\vspace{5pt} +} + +% Local Variables: +% mode: LaTeX +% TeX-master: "" +% End: + +% $Id$ + + + + |