\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}
Reset 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}
Reset 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}
Write 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: 
