aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc/Program.tex
diff options
context:
space:
mode:
authorGravatar filliatr <filliatr@85f007b7-540e-0410-9357-904b9bb8a0f7>2000-12-12 22:36:15 +0000
committerGravatar filliatr <filliatr@85f007b7-540e-0410-9357-904b9bb8a0f7>2000-12-12 22:36:15 +0000
commitb6018c78b25da14d4f44cf10de692f968cba1e98 (patch)
treec152b9761b70cbc554efdc2f05f3a995444ed259 /doc/Program.tex
parent88e2679b89a32189673b808acfe3d6181a38c000 (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/Program.tex')
-rw-r--r--doc/Program.tex850
1 files changed, 850 insertions, 0 deletions
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: