1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
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}
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:
|