summaryrefslogtreecommitdiff
path: root/doc/refman/Program.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/refman/Program.tex')
-rw-r--r--doc/refman/Program.tex491
1 files changed, 491 insertions, 0 deletions
diff --git a/doc/refman/Program.tex b/doc/refman/Program.tex
new file mode 100644
index 00000000..ed1e6e63
--- /dev/null
+++ b/doc/refman/Program.tex
@@ -0,0 +1,491 @@
+\def\Program{\textsc{Program}}
+\def\Russel{\textsc{Russel}}
+
+\achapter{The \Program{} tactic}
+\label{Program}
+\aauthor{Matthieu Sozeau}
+\index{Program}
+
+\begin{flushleft}
+ \em The status of \Program is experimental.
+\end{flushleft}
+
+We present here the \Coq\ \Program tactic commands, used to build certified
+\Coq programs, elaborating them from their algorithmic skeleton and a
+rich specification. It can be sought of as a dual of extraction \ref{Extraction}.
+The languages available as input are currently restricted to \Coq's term
+language, but may be extended to \ocaml{}, \textsc{Haskell} and others
+in the future. Input terms and types are typed in an extended system (\Russel) and
+interpreted into \Coq\ terms. The interpretation process may produce
+some proof obligations which need to be resolved to create the final term.
+
+\asection{Elaborating programs}
+\comindex{Program Fixpoint}
+
+The next two commands are similar to they standard counterparts
+\ref{Simpl-definitions} and \ref{Fixpoint} in that
+they define constants. However, they may require the user to prove some
+goals to construct the final definitions.
+
+\section{\tt Program Definition {\ident} := {\term}.
+ \comindex{Program Definition}\label{ProgramDefinition}}
+
+This command types the value {\term} in \Russel and generate subgoals
+corresponding to proof obligations. Once solved, it binds the final
+\Coq\ term to the name {\ident} in the environment.
+
+\begin{ErrMsgs}
+\item \errindex{{\ident} already exists}
+\end{ErrMsgs}
+
+\begin{Variants}
+\item {\tt Program Definition {\ident} {\tt :}{\term$_1$} :=
+ {\term$_2$}.}\\
+ It interprets the type {\term$_1$}, potentially generating proof
+ obligations to be resolved. Once done with them, we have a \Coq\ type
+ {\term$_1'$}. It then checks that the type of the interpretation of
+ {\term$_2$} is coercible to {\term$_1'$}, and registers {\ident} as
+ being of type {\term$_1'$} once the set of obligations generated
+ during the interpretation of {\term$_2$} and the aforementioned
+ coercion derivation are solved.
+\item {\tt Program Definition {\ident} {\binder$_1$}\ldots{\binder$_n$}
+ {\tt :}\term$_1$ {\tt :=} {\term$_2$}.}\\
+ This is equivalent to \\
+ {\tt Program Definition\,{\ident}\,{\tt :\,forall}\,%
+ {\binder$_1$}\ldots{\binder$_n$}{\tt ,}\,\term$_1$\,{\tt :=}}\,%
+ {\tt fun}\,{\binder$_1$}\ldots{\binder$_n$}\,{\tt =>}\,{\term$_2$}\,%
+ {\tt .}
+\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}
+
+\section{\tt Program Fixpoint {\ident} {\params} {\tt \{order\}} : type$_0$ := \term$_0$
+ \comindex{Program Fixpoint}
+ \label{ProgramFixpoint}}
+
+This command allows to define objects using a fixed point
+construction. The meaning of this declaration is to define {\it ident}
+a recursive function with arguments specified by
+{\binder$_1$}\ldots{\binder$_n$} such that {\it ident} applied to
+arguments corresponding to these binders has type \type$_0$, and is
+equivalent to the expression \term$_0$. The type of the {\ident} is
+consequently {\tt forall {\params} {\tt,} \type$_0$}
+and the value is equivalent to {\tt fun {\params} {\tt =>} \term$_0$}.
+
+There are two ways to define fixpoints with \Program{}, structural and
+well-founded recursion.
+
+\subsection{\tt Program Fixpoint {\ident} {\params} {\tt \{struct}
+ \ident$_0$ {\tt \}} : type$_0$ := \term$_0$
+ \comindex{Program Fixpoint Struct}
+ \label{ProgramFixpointStruct}}
+
+To be accepted, a structural {\tt Fixpoint} definition has to satisfy some
+syntactical constraints on a special argument called the decreasing
+argument. They are needed to ensure that the {\tt Fixpoint} definition
+always terminates. The point of the {\tt \{struct \ident {\tt \}}}
+annotation is to let the user tell the system which argument decreases
+along the recursive calls. This annotation may be left implicit for
+fixpoints with one argument. For instance, one can define the identity
+function on naturals as :
+
+\begin{coq_example}
+Program Fixpoint id (n : nat) : { x : nat | x = n } :=
+ match n with
+ | O => O
+ | S p => S (id p)
+ end.
+\end{coq_example}
+
+The {\tt match} 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:0:, and when \verb:n: equals
+\verb:(S p): we return \verb:(S (id p)):.
+
+The {\tt match} operator is formally described
+in detail in Section~\ref{Caseexpr}. The system recognizes that in
+the inductive call {\tt (id p)} the argument actually
+decreases because it is a {\em pattern variable} coming from {\tt match
+ n with}.
+
+Here again, proof obligations may be generated. In our example, we would
+have one for each branch:
+\begin{coq_example}
+Show.
+\end{coq_example}
+
+% \subsection{\tt Program Fixpoint {\ident} {(\ident_$_0$ : \type_$_0$)
+% \cdots (\ident_$_n$ : \type_$_n$)} {\tt \{wf}
+% \ident$_i$ \term_{wf} {\tt \}} : type$_t$ := \term$_0$
+% \comindex{Program Fixpoint Wf}
+% \label{ProgramFixpointWf}}
+
+% To be accepted, a well-founded {\tt Fixpoint} definition has to satisfy some
+% logical constraints on the decreasing argument.
+% They are needed to ensure that the {\tt Fixpoint} definition
+% always terminates. The point of the {\tt \{wf \ident \term {\tt \}}}
+% annotation is to let the user tell the system which argument decreases
+% in which well-founded relation along the recursive calls.
+% The term \term$_0$ will be typed in a different context than usual,
+% The typing problem will in fact be reduced to:
+
+% % \begin{center}
+% % {\tt forall} {\params} {\ident : (\ident$_0$ : type$_0$) \cdots
+% % \{ \ident$_i'$ : \type$_i$ | \term_{wf} \ident$_i'$ \ident$_i$ \}
+% % \cdots (\ident$_n$ : type$_n$), type$_t$} : type$_t$ := \term$_0$
+% % \end{center}
+
+% \begin{coq_example}
+% Program Fixpoint id (n : nat) : { x : nat | x = n } :=
+% match n with
+% | O => O
+% | S p => S (id p)
+% end
+% \end{coq_example}
+
+% The {\tt match} 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:0:, and when \verb:n: equals
+% \verb:(S p): we return \verb:(S (id p)):.
+
+% The {\tt match} operator is formally described
+% in detail in Section~\ref{Caseexpr}. The system recognizes that in
+% the inductive call {\tt (id p)} the argument actually
+% decreases because it is a {\em pattern variable} coming from {\tt match
+% n with}.
+
+% Here again, proof obligations may be generated. In our example, we would
+% have one for each branch:
+% \begin{coq_example}
+% Show.
+% \end{coq_example}
+% \begin{coq_eval}
+% Abort.
+% \end{coq_eval}
+
+
+
+
+% \asubsection{A detailed example: Euclidean division}
+
+% The file {\tt Euclid} 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*}
+
+% This module contains a theorem {\tt eucl\_dev}, and its extracted term
+% is of type
+% \begin{verbatim}
+% forall b:nat, b > 0 -> forall a:nat, diveucl a b
+% \end{verbatim}
+% where {\tt diveucl} is a type for the pair of the quotient and the modulo.
+% We can now extract this program to \ocaml:
+
+% \begin{coq_eval}
+% Reset Initial.
+% \end{coq_eval}
+% \begin{coq_example}
+% Require Import Euclid.
+% Extraction Inline Wf_nat.gt_wf_rec Wf_nat.lt_wf_rec.
+% Recursive Extraction eucl_dev.
+% \end{coq_example}
+
+% The inlining of {\tt gt\_wf\_rec} and {\tt lt\_wf\_rec} is not
+% mandatory. It only enhances readability of extracted code.
+% You can then copy-paste the output to a file {\tt euclid.ml} or let
+% \Coq\ do it for you with the following command:
+
+% \begin{coq_example}
+% Extraction "euclid" eucl_dev.
+% \end{coq_example}
+
+% Let us play the resulting program:
+
+% \begin{verbatim}
+% # #use "euclid.ml";;
+% type sumbool = Left | Right
+% type nat = O | S of nat
+% type diveucl = Divex of nat * nat
+% val minus : nat -> nat -> nat = <fun>
+% val le_lt_dec : nat -> nat -> sumbool = <fun>
+% val le_gt_dec : nat -> nat -> sumbool = <fun>
+% val eucl_dev : nat -> nat -> diveucl = <fun>
+% # 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 \ocaml\ integers:
+% \begin{verbatim}
+% # let rec i2n = function 0 -> O | n -> S (i2n (n-1));;
+% val i2n : int -> nat = <fun>
+% # let rec n2i = function O -> 0 | S p -> 1+(n2i p);;
+% val n2i : nat -> int = <fun>
+% # let div a b =
+% let Divex (q,r) = eucl_dev (i2n b) (i2n a) in (n2i q, n2i r);;
+% div : int -> int -> int * int = <fun>
+% # div 173 15;;
+% - : int * int = 11, 8
+% \end{verbatim}
+
+% \asubsection{Another detailed example: Heapsort}
+
+% The file {\tt Heap.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. The main function is {\tt
+% treesort}, whose type is shown below:
+
+
+% \begin{coq_eval}
+% Reset Initial.
+% Require Import Relation_Definitions.
+% Require Import List.
+% Require Import Sorting.
+% Require Import Permutation.
+% \end{coq_eval}
+% \begin{coq_example}
+% Require Import Heap.
+% Check treesort.
+% \end{coq_example}
+
+% Let's now extract this function:
+
+% \begin{coq_example}
+% Extraction Inline sort_rec is_heap_rec.
+% Extraction NoInline list_to_heap.
+% Extraction "heapsort" treesort.
+% \end{coq_example}
+
+% One more time, the {\tt Extraction Inline} and {\tt NoInline}
+% directives are cosmetic. Without it, everything goes right,
+% but the output is less readable.
+% Here is the produced file {\tt heapsort.ml}:
+
+% \begin{verbatim}
+% type nat =
+% | O
+% | S of nat
+
+% type 'a sig2 =
+% 'a
+% (* singleton inductive, whose constructor was exist2 *)
+
+% type sumbool =
+% | Left
+% | Right
+
+% type 'a list =
+% | Nil
+% | Cons of 'a * 'a list
+
+% type 'a multiset =
+% 'a -> nat
+% (* singleton inductive, whose constructor was Bag *)
+
+% type 'a merge_lem =
+% 'a list
+% (* singleton inductive, whose constructor was merge_exist *)
+
+% (** val merge : ('a1 -> 'a1 -> sumbool) -> ('a1 -> 'a1 -> sumbool) ->
+% 'a1 list -> 'a1 list -> 'a1 merge_lem **)
+
+% let rec merge leA_dec eqA_dec l1 l2 =
+% match l1 with
+% | Nil -> l2
+% | Cons (a, l) ->
+% let rec f = function
+% | Nil -> Cons (a, l)
+% | Cons (a0, l3) ->
+% (match leA_dec a a0 with
+% | Left -> Cons (a,
+% (merge leA_dec eqA_dec l (Cons (a0, l3))))
+% | Right -> Cons (a0, (f l3)))
+% in f l2
+
+% type 'a tree =
+% | Tree_Leaf
+% | Tree_Node of 'a * 'a tree * 'a tree
+
+% type 'a insert_spec =
+% 'a tree
+% (* singleton inductive, whose constructor was insert_exist *)
+
+% (** val insert : ('a1 -> 'a1 -> sumbool) -> ('a1 -> 'a1 -> sumbool) ->
+% 'a1 tree -> 'a1 -> 'a1 insert_spec **)
+
+% let rec insert leA_dec eqA_dec t a =
+% match t with
+% | Tree_Leaf -> Tree_Node (a, Tree_Leaf, Tree_Leaf)
+% | Tree_Node (a0, t0, t1) ->
+% let h3 = fun x -> insert leA_dec eqA_dec t0 x in
+% (match leA_dec a0 a with
+% | Left -> Tree_Node (a0, t1, (h3 a))
+% | Right -> Tree_Node (a, t1, (h3 a0)))
+
+% type 'a build_heap =
+% 'a tree
+% (* singleton inductive, whose constructor was heap_exist *)
+
+% (** val list_to_heap : ('a1 -> 'a1 -> sumbool) -> ('a1 -> 'a1 ->
+% sumbool) -> 'a1 list -> 'a1 build_heap **)
+
+% let rec list_to_heap leA_dec eqA_dec = function
+% | Nil -> Tree_Leaf
+% | Cons (a, l0) ->
+% insert leA_dec eqA_dec (list_to_heap leA_dec eqA_dec l0) a
+
+% type 'a flat_spec =
+% 'a list
+% (* singleton inductive, whose constructor was flat_exist *)
+
+% (** val heap_to_list : ('a1 -> 'a1 -> sumbool) -> ('a1 -> 'a1 ->
+% sumbool) -> 'a1 tree -> 'a1 flat_spec **)
+
+% let rec heap_to_list leA_dec eqA_dec = function
+% | Tree_Leaf -> Nil
+% | Tree_Node (a, t0, t1) -> Cons (a,
+% (merge leA_dec eqA_dec (heap_to_list leA_dec eqA_dec t0)
+% (heap_to_list leA_dec eqA_dec t1)))
+
+% (** val treesort : ('a1 -> 'a1 -> sumbool) -> ('a1 -> 'a1 -> sumbool)
+% -> 'a1 list -> 'a1 list sig2 **)
+
+% let treesort leA_dec eqA_dec l =
+% heap_to_list leA_dec eqA_dec (list_to_heap leA_dec eqA_dec l)
+
+% \end{verbatim}
+
+% Let's test it:
+% % Format.set_margin 72;;
+% \begin{verbatim}
+% # #use "heapsort.ml";;
+% type sumbool = Left | Right
+% type nat = O | S of nat
+% type 'a tree = Tree_Leaf | Tree_Node of 'a * 'a tree * 'a tree
+% type 'a list = Nil | Cons of 'a * 'a list
+% val merge :
+% ('a -> 'a -> sumbool) -> 'b -> 'a list -> 'a list -> 'a list = <fun>
+% val heap_to_list :
+% ('a -> 'a -> sumbool) -> 'b -> 'a tree -> 'a list = <fun>
+% val insert :
+% ('a -> 'a -> sumbool) -> 'b -> 'a tree -> 'a -> 'a tree = <fun>
+% val list_to_heap :
+% ('a -> 'a -> sumbool) -> 'b -> 'a list -> 'a tree = <fun>
+% val treesort :
+% ('a -> 'a -> sumbool) -> 'b -> 'a list -> 'a list = <fun>
+% \end{verbatim}
+
+% One can remark that the argument of {\tt treesort} corresponding to
+% {\tt eqAdec} is never used in the informative part of the terms,
+% only in the logical parts. So the extracted {\tt treesort} never use
+% it, hence this {\tt 'b} argument. We will use {\tt ()} for this
+% argument. Only remains the {\tt leAdec}
+% argument (of type {\tt 'a -> 'a -> sumbool}) to really provide.
+
+% \begin{verbatim}
+% # let leAdec x y = if x <= y then Left else Right;;
+% val leAdec : 'a -> 'a -> sumbool = <fun>
+% # let rec listn = function 0 -> Nil
+% | n -> Cons(Random.int 10000,listn (n-1));;
+% val listn : int -> int list = <fun>
+% # treesort leAdec () (listn 9);;
+% - : int list = Cons (160, Cons (883, Cons (1874, Cons (3275, Cons
+% (5392, Cons (7320, Cons (8512, Cons (9632, Cons (9876, Nil)))))))))
+% \end{verbatim}
+
+% Some tests on longer lists (10000 elements) show that the program is
+% quite efficient for Caml code.
+
+
+% \asubsection{The Standard Library}
+
+% As a test, we propose an automatic extraction of the
+% Standard Library of \Coq. In particular, we will find back the
+% two previous examples, {\tt Euclid} and {\tt Heapsort}.
+% Go to directory {\tt contrib/extraction/test} of the sources of \Coq,
+% and run commands:
+% \begin{verbatim}
+% make tree; make
+% \end{verbatim}
+% This will extract all Standard Library files and compile them.
+% It is done via many {\tt Extraction Module}, with some customization
+% (see subdirectory {\tt custom}).
+
+% %The result of this extraction of the Standard Library can be browsed
+% %at URL
+% %\begin{flushleft}
+% %\url{http://www.lri.fr/~letouzey/extraction}.
+% %\end{flushleft}
+
+% %Reals theory is normally not extracted, since it is an axiomatic
+% %development. We propose nonetheless a dummy realization of those
+% %axioms, to test, run: \\
+% %
+% %\mbox{\tt make reals}\\
+
+% This test works also with Haskell. In the same directory, run:
+% \begin{verbatim}
+% make tree; make -f Makefile.haskell
+% \end{verbatim}
+% The haskell compiler currently used is {\tt hbc}. Any other should
+% also work, just adapt the {\tt Makefile.haskell}. In particular {\tt
+% ghc} is known to work.
+
+% \asubsection{Extraction's horror museum}
+
+% Some pathological examples of extraction are grouped in the file
+% \begin{verbatim}
+% contrib/extraction/test_extraction.v
+% \end{verbatim}
+% of the sources of \Coq.
+
+% \asubsection{Users' Contributions}
+
+% Several of the \Coq\ Users' Contributions use extraction to produce
+% certified programs. In particular the following ones have an automatic
+% extraction test (just run {\tt make} in those directories):
+
+% \begin{itemize}
+% \item Bordeaux/Additions
+% \item Bordeaux/EXCEPTIONS
+% \item Bordeaux/SearchTrees
+% \item Dyade/BDDS
+% \item Lannion
+% \item Lyon/CIRCUITS
+% \item Lyon/FIRING-SQUAD
+% \item Marseille/CIRCUITS
+% \item Muenchen/Higman
+% \item Nancy/FOUnify
+% \item Rocq/ARITH/Chinese
+% \item Rocq/COC
+% \item Rocq/GRAPHS
+% \item Rocq/HIGMAN
+% \item Sophia-Antipolis/Stalmarck
+% \item Suresnes/BDD
+% \end{itemize}
+
+% Lannion, Rocq/HIGMAN and Lyon/CIRCUITS are a bit particular. They are
+% the only examples of developments where {\tt Obj.magic} are needed.
+% This is probably due to an heavy use of impredicativity.
+% After compilation those two examples run nonetheless,
+% thanks to the correction of the extraction~\cite{Let02}.
+
+% $Id: Program.tex 8688 2006-04-07 15:08:12Z msozeau $
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "Reference-Manual"
+%%% End: