aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc/Recursive-Definition.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/Recursive-Definition.tex')
-rwxr-xr-xdoc/Recursive-Definition.tex251
1 files changed, 251 insertions, 0 deletions
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$