diff options
| author | herbelin | 2001-04-25 06:56:26 +0000 |
|---|---|---|
| committer | herbelin | 2001-04-25 06:56:26 +0000 |
| commit | e566406dca5d2be69f42d95768973216fadb31a9 (patch) | |
| tree | dcbb5847edbe4b1f6907bd08070351611a0b66ad | |
| parent | 5476eaf21ab7ee056dfd0f12ef4c399367db78c9 (diff) | |
MAJ V7
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@8203 85f007b7-540e-0410-9357-904b9bb8a0f7
| -rw-r--r-- | doc/Cases.tex | 279 |
1 files changed, 146 insertions, 133 deletions
diff --git a/doc/Cases.tex b/doc/Cases.tex index 559c9e15b7..f9840bf5b9 100644 --- a/doc/Cases.tex +++ b/doc/Cases.tex @@ -7,15 +7,13 @@ 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. +\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. It is recommended to start variable names by +a lowercase letter. 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 @@ -25,7 +23,7 @@ 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 +``wildcard'' symbol) also matches any value, but does not bind anything. It may occur an arbitrary number of times in a pattern. Alias patterns written \texttt{(}{\sl pattern} \texttt{as} {\sl identifier}\texttt{)} are also accepted. This pattern matches the same values as {\sl pattern} @@ -72,9 +70,9 @@ to see the result of the expansion is by printing the term with 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 +rhs} in short) have the same type, then this type can be sometimes +synthesized, and so we can omit the \texttt{<>}. Otherwise +the predicate between \texttt{<>} has to be provided, like for the basic \texttt{Cases}. Let us illustrate through examples the different aspects of extended @@ -107,9 +105,10 @@ Fixpoint max [n,m:nat] : nat := 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: +The pattern-matching compilation 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. E.g. the +following example does not build a \texttt{Cases} expression. \begin{coq_example} Check [x:nat]<nat>Cases x of y => y end. @@ -123,7 +122,7 @@ Reset max. Fixpoint max [n:nat] : nat -> nat := [m:nat] Cases n m of O _ => m - | ((S n') as N) O => N + | ((S n') as p) O => p | (S n') (S m') => (S (max n' m')) end. \end{coq_example} @@ -146,7 +145,7 @@ 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 +sometimes it is comfortable to write patterns that admit 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 @@ -166,7 +165,7 @@ 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 +only if it 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}. @@ -189,19 +188,12 @@ 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, +Terms with useless patterns are not accepted by the +system. Here is an 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 @@ -228,8 +220,8 @@ Check [l:(List nat)]Cases l of 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' + (nil A) => (nil nat) + | (cons A _ l') => l' end. \end{coq_example} @@ -256,6 +248,7 @@ Definition length := [n:nat][l:(listn n)] n. Just for illustrating pattern matching, we can define it by case analysis: + \begin{coq_example} Reset length. Definition length := [n:nat][l:(listn n)] @@ -268,6 +261,10 @@ Definition length := [n:nat][l:(listn n)] We can understand the meaning of this definition using the same notions of usual pattern matching. +% +% Constraining of dependencies is not longer valid in V7 +% +\iffalse Now suppose we split the second pattern of \texttt{length} into two cases so to give an alternative definition using nested patterns: @@ -332,7 +329,10 @@ expansion of \texttt{length3} is completely different. \texttt{length1} and In practice the user can think about the patterns as independent and it is the expansion algorithm that cares to relate them. \\ - +\fi +% +% +% \asubsection{When the elimination predicate must be provided} The examples given so far do not need an explicit elimination predicate @@ -360,7 +360,7 @@ 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 +For example, an equivalent definition for \texttt{concat} (even though the matching on the second term is trivial) would have been: \begin{coq_example} @@ -373,7 +373,7 @@ Fixpoint concat [n:nat; l:(listn n)] : (m:nat) (listn m) -> (listn (plus n m)) end. \end{coq_example} -Note that this time, the predicate \texttt{[n,\_:nat](listn (plus n +Notice 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$ @@ -383,7 +383,11 @@ number of dependencies of the type of $e_1, e_2,\ldots e_n$ 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: +correct Coq raises an error message. For example: + +\begin{coq_eval} +Reset concat. +\end{coq_eval} \begin{coq_example} Fixpoint concat [n:nat; l:(listn n)] @@ -397,14 +401,14 @@ Fixpoint concat [n:nat; l:(listn n)] \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 +on the object(s) matched. But it may depend and the typical case is when we write a proof by induction or a function that yields an object of 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: +$n$ builds a list of length $n$ containing zeros as follows: \begin{coq_example} Fixpoint buildlist [n:nat] : (listn n) := @@ -427,29 +431,29 @@ Inductive LE : nat->nat->Prop := \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)}: + \texttt{(n,m:nat) (LE n m)}\verb=\/=\texttt{(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) => + | ((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)) + (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. +because we destructure two arguments of \texttt{nat} which is a +non-dependent type. Notice that 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 +\leq n$). Then, in expression \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.$ @@ -487,19 +491,19 @@ Here is a summary of the error messages corresponding to each situation: 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 +\item \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} +\item \sverb{Found a constructor of inductive type} {\term} + \sverb{while a constructor of} {\term} \sverb{is expected} \end{itemize} \item the pattern matching is not exhaustive \begin{itemize} -\item \sverb{This pattern-matching is not exhaustive} +\item \sverb{Non exhaustive pattern-matching} \end{itemize} \item the elimination predicate provided to \texttt{Cases} has not the expected arity @@ -510,96 +514,105 @@ Here is a summary of the error messages corresponding to each situation: 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). - +\item the whole expression is wrongly typed + +% CADUC ? +% , 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}. - 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: +\item there is a type mismatch between the different branches \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:} + \item {\tt Unable to infer a Cases predicate\\ +Either there is a type incompatiblity or the problem involves dependencies} \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} + Then the user should provide an elimination predicate. + +% Obsolete ? +% \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} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % LA PROPAGATION DES CONTRAINTES ARRIERE N'EST PAS FAITE DANS LA V7 +% TODO +% \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. +% 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} |
