~ubuntu-branches/ubuntu/wily/coq-doc/wily

« back to all changes in this revision

Viewing changes to doc/refman/RefMan-tacex.tex

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu, Stéphane Glondu, Samuel Mimram
  • Date: 2010-01-07 22:50:39 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100107225039-n3cq82589u0qt0s2
Tags: 8.2pl1-1
[ Stéphane Glondu ]
* New upstream release (Closes: #563669)
  - remove patches
* Packaging overhaul:
  - use git, advertise it in Vcs-* fields of debian/control
  - use debhelper 7 and dh with override
  - use source format 3.0 (quilt)
* debian/control:
  - set Maintainer to d-o-m, set Uploaders to Sam and myself
  - add Homepage field
  - bump Standards-Version to 3.8.3
* Register PDF documentation into doc-base
* Add debian/watch
* Update debian/copyright

[ Samuel Mimram ]
* Change coq-doc's description to mention that it provides documentation in
  pdf format, not postscript, closes: #543545.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
\chapter[Detailed examples of tactics]{Detailed examples of tactics\label{Tactics-examples}}
 
2
 
 
3
This chapter presents detailed examples of certain tactics, to
 
4
illustrate their behavior.
 
5
 
 
6
\section[\tt refine]{\tt refine\tacindex{refine}
 
7
\label{refine-example}}
 
8
 
 
9
This tactic applies to any goal. It behaves like {\tt exact} with a
 
10
big difference : the user can leave some holes (denoted by \texttt{\_} or 
 
11
{\tt (\_:}{\it type}{\tt )}) in the term. 
 
12
{\tt refine} will generate as many
 
13
subgoals as they are holes in the term. The type of holes must be
 
14
either synthesized by the system or declared by an
 
15
explicit cast like \verb|(\_:nat->Prop)|. This low-level
 
16
tactic can be useful to advanced users.
 
17
 
 
18
%\firstexample
 
19
\Example
 
20
 
 
21
\begin{coq_example*}
 
22
Inductive Option : Set :=
 
23
  | Fail : Option
 
24
  | Ok : bool -> Option.
 
25
\end{coq_example}
 
26
\begin{coq_example}
 
27
Definition get : forall x:Option, x <> Fail -> bool.
 
28
refine
 
29
 (fun x:Option =>
 
30
    match x return x <> Fail -> bool with
 
31
    | Fail => _
 
32
    | Ok b => fun _ => b
 
33
    end).
 
34
intros; absurd (Fail = Fail); trivial.
 
35
\end{coq_example}
 
36
\begin{coq_example*}
 
37
Defined.
 
38
\end{coq_example*}
 
39
 
 
40
% \example{Using Refine to build a poor-man's ``Cases'' tactic}
 
41
 
 
42
% \texttt{Refine} is actually the only way for the user to do
 
43
% a proof with the same structure as a {\tt Cases} definition. Actually,
 
44
% the tactics \texttt{case} (see \ref{case}) and \texttt{Elim} (see
 
45
% \ref{elim}) only allow one step of elementary induction. 
 
46
 
 
47
% \begin{coq_example*}
 
48
% Require Bool.
 
49
% Require Arith.
 
50
% \end{coq_example*}
 
51
% %\begin{coq_eval}
 
52
% %Abort.
 
53
% %\end{coq_eval}
 
54
% \begin{coq_example}
 
55
% Definition one_two_or_five := [x:nat]
 
56
%   Cases x of
 
57
%     (1) => true
 
58
%   | (2) => true
 
59
%   | (5) => true
 
60
%   | _ => false
 
61
%   end.
 
62
% Goal (x:nat)(Is_true (one_two_or_five x)) -> x=(1)\/x=(2)\/x=(5).
 
63
% \end{coq_example}
 
64
 
 
65
% A traditional script would be the following:
 
66
 
 
67
% \begin{coq_example*}
 
68
% Destruct x.
 
69
% Tauto.
 
70
% Destruct n.
 
71
% Auto.
 
72
% Destruct n0.
 
73
% Auto.
 
74
% Destruct n1.
 
75
% Tauto.
 
76
% Destruct n2.
 
77
% Tauto.
 
78
% Destruct n3.
 
79
% Auto.
 
80
% Intros; Inversion H.
 
81
% \end{coq_example*}
 
82
 
 
83
% With the tactic \texttt{Refine}, it becomes quite shorter:
 
84
 
 
85
% \begin{coq_example*}
 
86
% Restart.
 
87
% \end{coq_example*}
 
88
% \begin{coq_example}
 
89
% Refine [x:nat]
 
90
%   <[y:nat](Is_true (one_two_or_five y))->(y=(1)\/y=(2)\/y=(5))>
 
91
%   Cases x of
 
92
%     (1) => [H]?
 
93
%   | (2) => [H]?
 
94
%   | (5) => [H]?
 
95
%   | n => [H](False_ind ? H)
 
96
%   end; Auto.
 
97
% \end{coq_example}
 
98
% \begin{coq_eval}
 
99
% Abort.
 
100
% \end{coq_eval}
 
101
 
 
102
\section[\tt eapply]{\tt eapply\tacindex{eapply}
 
103
\label{eapply-example}}
 
104
\Example
 
105
Assume we have a relation on {\tt nat} which is transitive:
 
106
 
 
107
\begin{coq_example*}
 
108
Variable R : nat -> nat -> Prop.
 
109
Hypothesis Rtrans : forall x y z:nat, R x y -> R y z -> R x z.
 
110
Variables n m p : nat.
 
111
Hypothesis Rnm : R n m.
 
112
Hypothesis Rmp : R m p.
 
113
\end{coq_example*}
 
114
 
 
115
Consider the goal {\tt (R n p)} provable using the transitivity of
 
116
{\tt R}:
 
117
 
 
118
\begin{coq_example*}
 
119
Goal R n p.
 
120
\end{coq_example*}
 
121
 
 
122
The direct application of {\tt Rtrans} with {\tt apply} fails because
 
123
no value for {\tt y} in {\tt Rtrans} is found by {\tt apply}:
 
124
 
 
125
\begin{coq_eval}
 
126
Set Printing Depth 50.
 
127
(********** The following is not correct and should produce **********)
 
128
(**** Error: generated subgoal (R n ?17) has metavariables in it *****)
 
129
\end{coq_eval}
 
130
\begin{coq_example}
 
131
apply Rtrans.
 
132
\end{coq_example}
 
133
 
 
134
A solution is to rather apply {\tt (Rtrans n m p)}.
 
135
 
 
136
\begin{coq_example}
 
137
apply (Rtrans n m p).
 
138
\end{coq_example}
 
139
 
 
140
\begin{coq_eval}
 
141
Undo.
 
142
\end{coq_eval}
 
143
 
 
144
More elegantly, {\tt apply Rtrans with (y:=m)} allows to only mention
 
145
the unknown {\tt m}:
 
146
 
 
147
\begin{coq_example}
 
148
 
 
149
  apply Rtrans with (y := m).
 
150
\end{coq_example}
 
151
 
 
152
\begin{coq_eval}
 
153
Undo.
 
154
\end{coq_eval}
 
155
 
 
156
Another solution is to mention the proof of {\tt (R x y)} in {\tt
 
157
Rtrans}...
 
158
 
 
159
\begin{coq_example}
 
160
 
 
161
  apply Rtrans with (1 := Rnm).
 
162
\end{coq_example}
 
163
 
 
164
\begin{coq_eval}
 
165
Undo.
 
166
\end{coq_eval}
 
167
 
 
168
... or the proof of {\tt (R y z)}:
 
169
 
 
170
\begin{coq_example}
 
171
 
 
172
  apply Rtrans with (2 := Rmp).
 
173
\end{coq_example}
 
174
 
 
175
\begin{coq_eval}
 
176
Undo.
 
177
\end{coq_eval}
 
178
 
 
179
On the opposite, one can use {\tt eapply} which postpone the problem
 
180
of finding {\tt m}. Then one can apply the hypotheses {\tt Rnm} and {\tt
 
181
Rmp}. This instantiates the existential variable and completes the proof.
 
182
 
 
183
\begin{coq_example}
 
184
eapply Rtrans.
 
185
apply Rnm.
 
186
apply Rmp.
 
187
\end{coq_example}
 
188
 
 
189
\begin{coq_eval}
 
190
Reset R.
 
191
\end{coq_eval}
 
192
 
 
193
\section[{\tt Scheme}]{{\tt Scheme}\comindex{Scheme}
 
194
\label{Scheme-examples}}
 
195
 
 
196
\firstexample
 
197
\example{Induction scheme for \texttt{tree} and \texttt{forest}}
 
198
 
 
199
The definition of principle of mutual induction for {\tt tree} and
 
200
{\tt forest} over the sort {\tt Set} is defined by the command:
 
201
 
 
202
\begin{coq_eval}
 
203
Reset Initial.
 
204
Variables A B : 
 
205
              Set.
 
206
\end{coq_eval}
 
207
 
 
208
\begin{coq_example*}
 
209
Inductive tree : Set :=
 
210
    node : A -> forest -> tree
 
211
with forest : Set :=
 
212
  | leaf : B -> forest
 
213
  | cons : tree -> forest -> forest.
 
214
 
 
215
Scheme tree_forest_rec := Induction for tree Sort Set
 
216
  with forest_tree_rec := Induction for forest Sort Set.
 
217
\end{coq_example*}
 
218
 
 
219
You may now look at the type of {\tt tree\_forest\_rec}:
 
220
 
 
221
\begin{coq_example}
 
222
Check tree_forest_rec.
 
223
\end{coq_example}
 
224
 
 
225
This principle involves two different predicates for {\tt trees} and
 
226
{\tt forests}; it also has three premises each one corresponding to a
 
227
constructor of one of the inductive definitions.
 
228
 
 
229
The principle {\tt forest\_tree\_rec} shares exactly the same
 
230
premises, only the conclusion now refers to the property of forests.
 
231
 
 
232
\begin{coq_example}
 
233
Check forest_tree_rec.
 
234
\end{coq_example}
 
235
 
 
236
\example{Predicates {\tt odd} and {\tt even} on naturals}
 
237
 
 
238
Let {\tt odd} and {\tt even} be inductively defined as:
 
239
 
 
240
% Reset Initial.
 
241
\begin{coq_eval}
 
242
Open Scope nat_scope.
 
243
\end{coq_eval}
 
244
 
 
245
\begin{coq_example*}
 
246
Inductive odd : nat -> Prop :=
 
247
    oddS : forall n:nat, even n -> odd (S n)
 
248
with even : nat -> Prop :=
 
249
  | evenO : even 0
 
250
  | evenS : forall n:nat, odd n -> even (S n).
 
251
\end{coq_example*}
 
252
 
 
253
The following command generates a powerful elimination
 
254
principle:
 
255
 
 
256
\begin{coq_example}
 
257
Scheme odd_even := Minimality for   odd Sort Prop
 
258
  with even_odd := Minimality for even Sort Prop.
 
259
\end{coq_example}
 
260
 
 
261
The type of {\tt odd\_even} for instance will be:
 
262
 
 
263
\begin{coq_example}
 
264
Check odd_even.
 
265
\end{coq_example}
 
266
 
 
267
The type of {\tt even\_odd} shares the same premises but the
 
268
conclusion is {\tt (n:nat)(even n)->(Q n)}.
 
269
 
 
270
\subsection[{\tt Combined Scheme}]{{\tt Combined Scheme}\comindex{Combined Scheme}
 
271
\label{CombinedScheme-examples}}
 
272
 
 
273
We can define the induction principles for trees and forests using:
 
274
\begin{coq_example}
 
275
Scheme tree_forest_ind := Induction for tree Sort Prop
 
276
  with forest_tree_ind := Induction for forest Sort Prop.
 
277
\end{coq_example}
 
278
 
 
279
Then we can build the combined induction principle which gives the
 
280
conjunction of the conclusions of each individual principle:
 
281
\begin{coq_example}
 
282
Combined Scheme tree_forest_mutind from tree_forest_ind, forest_tree_ind.
 
283
\end{coq_example}
 
284
 
 
285
The type of {\tt tree\_forest\_mutrec} will be:
 
286
\begin{coq_example}
 
287
Check tree_forest_mutind.
 
288
\end{coq_example}
 
289
 
 
290
\section[{\tt Functional Scheme} and {\tt functional induction}]{{\tt Functional Scheme} and {\tt functional induction}\comindex{Functional Scheme}\tacindex{functional induction}
 
291
\label{FunScheme-examples}}
 
292
 
 
293
\firstexample
 
294
\example{Induction scheme for \texttt{div2}}
 
295
 
 
296
We define the function \texttt{div2} as follows:
 
297
 
 
298
\begin{coq_eval}
 
299
Reset Initial.
 
300
\end{coq_eval}
 
301
 
 
302
\begin{coq_example*}
 
303
Require Import Arith.
 
304
Fixpoint div2 (n:nat) : nat :=
 
305
  match n with
 
306
  | O => 0
 
307
  | S O => 0
 
308
  | S (S n') => S (div2 n')
 
309
  end.
 
310
\end{coq_example*}
 
311
 
 
312
The definition of a principle of induction corresponding to the
 
313
recursive structure of \texttt{div2} is defined by the command:
 
314
 
 
315
\begin{coq_example}
 
316
Functional Scheme div2_ind := Induction for div2 Sort Prop.
 
317
\end{coq_example}
 
318
 
 
319
You may now look at the type of {\tt div2\_ind}:
 
320
 
 
321
\begin{coq_example}
 
322
Check div2_ind.
 
323
\end{coq_example}
 
324
 
 
325
We can now prove the following lemma using this principle:
 
326
 
 
327
 
 
328
\begin{coq_example*}
 
329
Lemma div2_le' : forall n:nat, div2 n <= n.
 
330
intro n.
 
331
 pattern n , (div2 n).
 
332
\end{coq_example*}
 
333
 
 
334
 
 
335
\begin{coq_example}
 
336
apply div2_ind; intros.
 
337
\end{coq_example}
 
338
 
 
339
\begin{coq_example*}
 
340
auto with arith.
 
341
auto with arith.
 
342
simpl; auto with arith.
 
343
Qed.
 
344
\end{coq_example*}
 
345
 
 
346
We can use directly the \texttt{functional induction}
 
347
(\ref{FunInduction}) tactic instead of the pattern/apply trick:
 
348
 
 
349
\begin{coq_example*}
 
350
Reset div2_le'.
 
351
Lemma div2_le : forall n:nat, div2 n <= n.
 
352
intro n.
 
353
\end{coq_example*}
 
354
 
 
355
\begin{coq_example}
 
356
functional induction (div2 n).
 
357
\end{coq_example}
 
358
 
 
359
\begin{coq_example*}
 
360
auto with arith.
 
361
auto with arith.
 
362
auto with arith.
 
363
Qed.
 
364
\end{coq_example*}
 
365
 
 
366
\Rem There is a difference between obtaining an induction scheme for a
 
367
function by using \texttt{Function} (see Section~\ref{Function}) and by
 
368
using \texttt{Functional Scheme} after a normal definition using
 
369
\texttt{Fixpoint} or \texttt{Definition}. See \ref{Function} for
 
370
details.
 
371
 
 
372
 
 
373
\example{Induction scheme for \texttt{tree\_size}}
 
374
 
 
375
\begin{coq_eval}
 
376
Reset Initial.
 
377
\end{coq_eval}
 
378
 
 
379
We define trees by the following mutual inductive type:
 
380
 
 
381
\begin{coq_example*}
 
382
Variable A : Set.
 
383
Inductive tree : Set :=
 
384
    node : A -> forest -> tree
 
385
with forest : Set :=
 
386
  | empty : forest
 
387
  | cons : tree -> forest -> forest.
 
388
\end{coq_example*}
 
389
 
 
390
We define the function \texttt{tree\_size} that computes the size
 
391
of a tree or a forest. Note that we use \texttt{Function} which
 
392
generally produces better principles.
 
393
 
 
394
\begin{coq_example*}                
 
395
Function tree_size (t:tree) : nat :=
 
396
  match t with
 
397
  | node A f => S (forest_size f)
 
398
  end
 
399
 with forest_size (f:forest) : nat :=
 
400
  match f with
 
401
  | empty => 0
 
402
  | cons t f' => (tree_size t + forest_size f')
 
403
  end.
 
404
\end{coq_example*}
 
405
 
 
406
Remark: \texttt{Function} generates itself non mutual induction
 
407
principles {\tt tree\_size\_ind} and {\tt forest\_size\_ind}:
 
408
 
 
409
\begin{coq_example}
 
410
Check tree_size_ind.
 
411
\end{coq_example}
 
412
 
 
413
The definition of mutual induction principles following the recursive
 
414
structure of \texttt{tree\_size} and \texttt{forest\_size} is defined
 
415
by the command:
 
416
 
 
417
\begin{coq_example*}
 
418
Functional Scheme tree_size_ind2 := Induction for tree_size Sort Prop
 
419
with forest_size_ind2 := Induction for forest_size Sort Prop.
 
420
\end{coq_example*}
 
421
 
 
422
You may now look at the type of {\tt tree\_size\_ind2}:
 
423
 
 
424
\begin{coq_example}
 
425
Check tree_size_ind2.
 
426
\end{coq_example}
 
427
 
 
428
 
 
429
 
 
430
 
 
431
\section[{\tt inversion}]{{\tt inversion}\tacindex{inversion}
 
432
\label{inversion-examples}}
 
433
 
 
434
\subsection*{Generalities about inversion}
 
435
 
 
436
When working with (co)inductive predicates, we are very often faced to
 
437
some of these situations:
 
438
\begin{itemize}
 
439
\item we have an inconsistent instance of an inductive predicate in the
 
440
  local context of hypotheses. Thus, the current goal can be trivially
 
441
  proved by absurdity. 
 
442
\item we have a hypothesis that is an instance of an inductive
 
443
  predicate, and the instance has some variables whose constraints we
 
444
  would like to derive.
 
445
\end{itemize}
 
446
 
 
447
The inversion tactics are very useful to simplify the work in these
 
448
cases. Inversion tools can be classified in three groups:
 
449
 
 
450
\begin{enumerate}
 
451
\item tactics for inverting an instance without stocking the inversion
 
452
  lemma in the context; this includes the tactics
 
453
  (\texttt{dependent})  \texttt{inversion} and
 
454
 (\texttt{dependent}) \texttt{inversion\_clear}.
 
455
\item commands for generating and stocking in the context the inversion
 
456
  lemma corresponding to an instance; this includes \texttt{Derive}
 
457
  (\texttt{Dependent}) \texttt{Inversion} and \texttt{Derive}
 
458
  (\texttt{Dependent}) \texttt{Inversion\_clear}.
 
459
\item tactics for inverting an instance using an already defined
 
460
  inversion lemma; this includes the tactic \texttt{inversion \ldots using}.
 
461
\end{enumerate}
 
462
 
 
463
As inversion proofs may be large in size, we recommend the user to
 
464
stock the lemmas whenever the same instance needs to be inverted
 
465
several times.
 
466
 
 
467
\firstexample
 
468
\example{Non-dependent inversion}
 
469
 
 
470
Let's consider the relation \texttt{Le} over natural numbers and the
 
471
following variables:
 
472
 
 
473
\begin{coq_eval}
 
474
Reset Initial.
 
475
\end{coq_eval}
 
476
 
 
477
\begin{coq_example*}
 
478
Inductive Le : nat -> nat -> Set :=
 
479
  | LeO : forall n:nat, Le 0 n
 
480
  | LeS : forall n m:nat, Le n m -> Le (S n) (S m).
 
481
Variable P : nat -> nat -> Prop.
 
482
Variable Q : forall n m:nat, Le n m -> Prop.
 
483
\end{coq_example*}
 
484
 
 
485
For example, consider the goal:
 
486
 
 
487
\begin{coq_eval}
 
488
Lemma ex : forall n m:nat, Le (S n) m -> P n m.
 
489
intros.
 
490
\end{coq_eval}
 
491
 
 
492
\begin{coq_example}
 
493
Show.
 
494
\end{coq_example}
 
495
 
 
496
To prove the goal we may need to reason by cases on \texttt{H} and to 
 
497
 derive that \texttt{m}  is necessarily of
 
498
the form $(S~m_0)$ for certain $m_0$ and that $(Le~n~m_0)$.  
 
499
Deriving these conditions corresponds to prove that the
 
500
only possible constructor of \texttt{(Le (S n) m)}  is
 
501
\texttt{LeS} and that we can invert the 
 
502
\texttt{->} in the type  of \texttt{LeS}.  
 
503
This inversion is possible because \texttt{Le} is the smallest set closed by
 
504
the constructors \texttt{LeO} and \texttt{LeS}.
 
505
 
 
506
\begin{coq_example}
 
507
inversion_clear H.
 
508
\end{coq_example}
 
509
 
 
510
Note that \texttt{m} has been substituted in the goal for \texttt{(S m0)}
 
511
and that the hypothesis \texttt{(Le n m0)} has been added to the
 
512
context.
 
513
 
 
514
Sometimes it is
 
515
interesting to have the equality \texttt{m=(S m0)} in the
 
516
context to use it after. In that case we can use \texttt{inversion} that
 
517
does not clear the equalities:
 
518
 
 
519
\begin{coq_example*}
 
520
Undo.
 
521
\end{coq_example*}
 
522
 
 
523
\begin{coq_example}
 
524
inversion H.
 
525
\end{coq_example}
 
526
 
 
527
\begin{coq_eval}
 
528
Undo.
 
529
\end{coq_eval}
 
530
 
 
531
\example{Dependent Inversion}
 
532
 
 
533
Let us consider the following goal:
 
534
 
 
535
\begin{coq_eval}
 
536
Lemma ex_dep : forall (n m:nat) (H:Le (S n) m), Q (S n) m H.
 
537
intros.
 
538
\end{coq_eval}
 
539
 
 
540
\begin{coq_example}
 
541
Show.
 
542
\end{coq_example}
 
543
 
 
544
As \texttt{H} occurs in the goal, we may want to reason by cases on its
 
545
structure and so, we would like  inversion tactics to
 
546
substitute \texttt{H} by the corresponding term in constructor form. 
 
547
Neither \texttt{Inversion} nor  {\tt Inversion\_clear} make such a
 
548
substitution. 
 
549
To have such a behavior we use the dependent inversion tactics:
 
550
 
 
551
\begin{coq_example}
 
552
dependent inversion_clear H.
 
553
\end{coq_example}
 
554
 
 
555
Note that \texttt{H} has been substituted by \texttt{(LeS n m0 l)} and
 
556
\texttt{m} by \texttt{(S m0)}.
 
557
 
 
558
\example{using already defined inversion  lemmas}
 
559
 
 
560
\begin{coq_eval}
 
561
Abort.
 
562
\end{coq_eval}
 
563
 
 
564
For example, to generate the inversion lemma for the instance
 
565
\texttt{(Le (S n) m)} and the sort \texttt{Prop} we do:
 
566
 
 
567
\begin{coq_example*}
 
568
Derive Inversion_clear leminv with (forall n m:nat, Le (S n) m) Sort
 
569
 Prop.
 
570
\end{coq_example*}
 
571
 
 
572
\begin{coq_example}
 
573
Check leminv.
 
574
\end{coq_example}
 
575
 
 
576
Then we can use the proven inversion lemma:
 
577
 
 
578
\begin{coq_example}
 
579
Show.
 
580
\end{coq_example}
 
581
 
 
582
\begin{coq_example}
 
583
inversion H using leminv.
 
584
\end{coq_example}
 
585
 
 
586
\begin{coq_eval}
 
587
Reset Initial.
 
588
\end{coq_eval}
 
589
 
 
590
\section[\tt dependent induction]{\tt dependent induction\label{dependent-induction-example}}
 
591
\def\depind{{\tt dependent induction}~}
 
592
\def\depdestr{{\tt dependent destruction}~}
 
593
 
 
594
The tactics \depind and \depdestr are another solution for inverting
 
595
inductive predicate instances and potentially doing induction at the
 
596
same time. It is based on the \texttt{BasicElim} tactic of Conor McBride which
 
597
works by abstracting each argument of an inductive instance by a variable
 
598
and constraining it by equalities afterwards. This way, the usual 
 
599
{\tt induction} and {\tt destruct} tactics can be applied to the
 
600
abstracted instance and after simplification of the equalities we get
 
601
the expected goals.
 
602
 
 
603
The abstracting tactic is called {\tt generalize\_eqs} and it takes as
 
604
argument an hypothesis to generalize. It uses the {\tt JMeq} datatype
 
605
defined in {\tt Coq.Logic.JMeq}, hence we need to require it before.
 
606
For example, revisiting the first example of the inversion documentation above:
 
607
 
 
608
\begin{coq_example*}
 
609
Require Import Coq.Logic.JMeq.
 
610
\end{coq_example*}
 
611
\begin{coq_eval}
 
612
Require Import Coq.Program.Equality.
 
613
\end{coq_eval}
 
614
 
 
615
\begin{coq_eval}
 
616
Inductive Le : nat -> nat -> Set :=
 
617
  | LeO : forall n:nat, Le 0 n
 
618
  | LeS : forall n m:nat, Le n m -> Le (S n) (S m).
 
619
Variable P : nat -> nat -> Prop.
 
620
Variable Q : forall n m:nat, Le n m -> Prop.
 
621
\end{coq_eval}
 
622
 
 
623
\begin{coq_example*}
 
624
Goal forall n m:nat, Le (S n) m -> P n m.
 
625
intros n m H.
 
626
\end{coq_example*}
 
627
\begin{coq_example}
 
628
generalize_eqs H.
 
629
\end{coq_example}
 
630
 
 
631
The index {\tt S n} gets abstracted by a variable here, but a
 
632
corresponding equality is added under the abstract instance so that no
 
633
information is actually lost. The goal is now almost ammenable to do induction
 
634
or case analysis. One should indeed first move {\tt n} into the goal to
 
635
strengthen it before doing induction, or {\tt n} will be fixed in
 
636
the inductive hypotheses (this does not matter for case analysis). 
 
637
As a rule of thumb, all the variables that appear inside constructors in
 
638
the indices of the hypothesis should be generalized. This is exactly
 
639
what the \texttt{generalize\_eqs\_vars} variant does:
 
640
 
 
641
\begin{coq_eval} 
 
642
Undo 1.
 
643
\end{coq_eval}
 
644
\begin{coq_example}
 
645
generalize_eqs_vars H.
 
646
induction H.
 
647
\end{coq_example}
 
648
 
 
649
As the hypothesis itself did not appear in the goal, we did not need to
 
650
use an heterogeneous equality to relate the new hypothesis to the old
 
651
one (which just disappeared here). However, the tactic works just a well
 
652
in this case, e.g.:
 
653
 
 
654
\begin{coq_eval}
 
655
Admitted.
 
656
\end{coq_eval}
 
657
 
 
658
\begin{coq_example}
 
659
Goal forall n m (p : Le (S n) m), Q (S n) m p.
 
660
intros n m p ; generalize_eqs_vars p.
 
661
\end{coq_example}
 
662
 
 
663
One drawback of this approach is that in the branches one will have to
 
664
substitute the equalities back into the instance to get the right
 
665
assumptions. Sometimes injection of constructors will also be needed to
 
666
recover the needed equalities. Also, some subgoals should be directly
 
667
solved because of inconsistent contexts arising from the constraints on 
 
668
 indices. The nice thing is that we can make a tactic based on
 
669
discriminate, injection and variants of substitution to automatically 
 
670
do such simplifications (which may involve the K axiom). 
 
671
This is what the {\tt simplify\_dep\_elim} tactic from
 
672
{\tt Coq.Program.Equality} does. For example, we might simplify the
 
673
previous goals considerably:
 
674
% \begin{coq_eval} 
 
675
% Abort.
 
676
% Goal forall n m:nat, Le (S n) m -> P n m.
 
677
% intros n m H ; generalize_eqs_vars H.
 
678
% \end{coq_eval}
 
679
 
 
680
\begin{coq_example}
 
681
induction p ; simplify_dep_elim.
 
682
\end{coq_example}
 
683
 
 
684
The higher-order tactic {\tt do\_depind} defined in {\tt
 
685
  Coq.Program.Equality} takes a tactic and combines the
 
686
building blocks we've seen with it: generalizing by equalities 
 
687
calling the given tactic with the
 
688
generalized induction hypothesis as argument and cleaning the subgoals
 
689
with respect to equalities. Its most important instantiations are
 
690
\depind and \depdestr that do induction or simply case analysis on the
 
691
generalized hypothesis. For example we can redo what we've done manually
 
692
with \depdestr:
 
693
 
 
694
\begin{coq_eval}
 
695
Abort.
 
696
\end{coq_eval}
 
697
\begin{coq_example*}
 
698
Require Import Coq.Program.Equality.
 
699
Lemma ex : forall n m:nat, Le (S n) m -> P n m.
 
700
intros n m H.
 
701
\end{coq_example*}
 
702
\begin{coq_example}
 
703
dependent destruction H.
 
704
\end{coq_example}
 
705
\begin{coq_eval}
 
706
Abort.
 
707
\end{coq_eval}
 
708
 
 
709
This gives essentially the same result as inversion. Now if the
 
710
destructed hypothesis actually appeared in the goal, the tactic would
 
711
still be able to invert it, contrary to {\tt dependent
 
712
 inversion}. Consider the following example on vectors:
 
713
 
 
714
\begin{coq_example*}
 
715
Require Import Coq.Program.Equality.
 
716
Set Implicit Arguments.
 
717
Variable A : Set.
 
718
Inductive vector : nat -> Type := 
 
719
| vnil : vector 0 
 
720
| vcons : A -> forall n, vector n -> vector (S n).
 
721
Goal forall n, forall v : vector (S n), 
 
722
  exists v' : vector n, exists a : A, v = vcons a v'.
 
723
  intros n v.
 
724
\end{coq_example*}
 
725
\begin{coq_example}
 
726
  dependent destruction v.
 
727
\end{coq_example}
 
728
\begin{coq_eval}
 
729
Abort.
 
730
\end{coq_eval}
 
731
 
 
732
In this case, the {\tt v} variable can be replaced in the goal by the
 
733
generalized hypothesis only when it has a type of the form {\tt vector
 
734
 (S n)}, that is only in the second case of the {\tt destruct}. The
 
735
first one is dismissed because {\tt S n <> 0}.
 
736
 
 
737
\subsection{A larger example}
 
738
 
 
739
Let's see how the technique works with {\tt induction} on inductive
 
740
predicates on a real example. We will develop an example application to the
 
741
theory of simply-typed lambda-calculus formalized in a dependently-typed style:
 
742
 
 
743
\begin{coq_example*}
 
744
Inductive type : Type :=
 
745
| base : type
 
746
| arrow : type -> type -> type.
 
747
Notation " t --> t' " := (arrow t t') (at level 20, t' at next level).
 
748
Inductive ctx : Type :=
 
749
| empty : ctx
 
750
| snoc : ctx -> type -> ctx.
 
751
Notation " G , tau " := (snoc G tau) (at level 20, t at next level).
 
752
Fixpoint conc (G D : ctx) : ctx :=
 
753
  match D with
 
754
    | empty => G
 
755
    | snoc D' x => snoc (conc G D') x
 
756
  end.
 
757
Notation " G ; D " := (conc G D) (at level 20).
 
758
Inductive term : ctx -> type -> Type :=
 
759
| ax : forall G tau, term (G, tau) tau
 
760
| weak : forall G tau, 
 
761
  term G tau -> forall tau', term (G, tau') tau
 
762
| abs : forall G tau tau', 
 
763
  term (G , tau) tau' -> term G (tau --> tau')
 
764
| app : forall G tau tau', 
 
765
  term G (tau --> tau') -> term G tau -> term G tau'.
 
766
\end{coq_example*}
 
767
 
 
768
We have defined types and contexts which are snoc-lists of types. We
 
769
also have a {\tt conc} operation that concatenates two contexts.
 
770
The {\tt term} datatype represents in fact the possible typing
 
771
derivations of the calculus, which are isomorphic to the well-typed
 
772
terms, hence the name. A term is either an application of:
 
773
\begin{itemize}
 
774
\item the axiom rule to type a reference to the first variable in a context,
 
775
\item the weakening rule to type an object in a larger context
 
776
\item the abstraction or lambda rule to type a function
 
777
\item the application to type an application of a function to an argument
 
778
\end{itemize}
 
779
 
 
780
Once we have this datatype we want to do proofs on it, like weakening:
 
781
 
 
782
\begin{coq_example*}
 
783
Lemma weakening : forall G D tau, term (G ; D) tau -> 
 
784
  forall tau', term (G , tau' ; D) tau.
 
785
\end{coq_example*}
 
786
\begin{coq_eval}
 
787
  Abort.
 
788
\end{coq_eval}
 
789
 
 
790
The problem here is that we can't just use {\tt induction} on the typing
 
791
derivation because it will forget about the {\tt G ; D} constraint
 
792
appearing in the instance. A solution would be to rewrite the goal as:
 
793
\begin{coq_example*}
 
794
Lemma weakening' : forall G' tau, term G' tau -> 
 
795
  forall G D, (G ; D) = G' ->
 
796
  forall tau', term (G, tau' ; D) tau.
 
797
\end{coq_example*}
 
798
\begin{coq_eval}
 
799
  Abort.
 
800
\end{coq_eval}
 
801
 
 
802
With this proper separation of the index from the instance and the right
 
803
induction loading (putting {\tt G} and {\tt D} after the inducted-on
 
804
hypothesis), the proof will go through, but it is a very tedious
 
805
process. One is also forced to make a wrapper lemma to get back the
 
806
more natural statement. The \depind tactic aleviates this trouble by
 
807
doing all of this plumbing of generalizing and substituting back automatically.
 
808
Indeed we can simply write:
 
809
 
 
810
\begin{coq_example*}
 
811
Require Import Coq.Program.Tactics.
 
812
Lemma weakening : forall G D tau, term (G ; D) tau -> 
 
813
  forall tau', term (G , tau' ; D) tau.
 
814
Proof with simpl in * ; simpl_depind ; auto.
 
815
  intros G D tau H. dependent induction H generalizing G D ; intros.
 
816
\end{coq_example*}
 
817
 
 
818
This call to \depind has an additional arguments which is a list of
 
819
variables appearing in the instance that should be generalized in the
 
820
goal, so that they can vary in the induction hypotheses. By default, all
 
821
variables appearing inside constructors (except in a parameter position)
 
822
of the instantiated hypothesis will be generalized automatically but
 
823
one can always give the list explicitely.
 
824
 
 
825
\begin{coq_example}
 
826
  Show.
 
827
\end{coq_example}
 
828
 
 
829
The {\tt simpl\_depind} tactic includes an automatic tactic that tries
 
830
to simplify equalities appearing at the beginning of induction
 
831
hypotheses, generally using trivial applications of
 
832
reflexiviy. In cases where the equality is not between constructor
 
833
forms though, one must help the automation by giving
 
834
some arguments, using the {\tt specialize} tactic.
 
835
 
 
836
\begin{coq_example*}
 
837
destruct D... apply weak ; apply ax. apply ax.
 
838
destruct D...
 
839
\end{coq_example*}
 
840
\begin{coq_example}
 
841
Show.
 
842
\end{coq_example}
 
843
\begin{coq_example}
 
844
  specialize (IHterm G empty).
 
845
\end{coq_example}
 
846
 
 
847
Then the automation can find the needed equality {\tt G = G} to narrow
 
848
the induction hypothesis further. This concludes our example.
 
849
 
 
850
\begin{coq_example}
 
851
  simpl_depind.
 
852
\end{coq_example}
 
853
 
 
854
\SeeAlso The induction \ref{elim}, case \ref{case} and inversion \ref{inversion} tactics.
 
855
 
 
856
\section[\tt autorewrite]{\tt autorewrite\label{autorewrite-example}}
 
857
 
 
858
Here are two examples of {\tt autorewrite} use. The first one ({\em Ackermann
 
859
function}) shows actually a quite basic use where there is no conditional
 
860
rewriting. The second one ({\em Mac Carthy function}) involves conditional
 
861
rewritings and shows how to deal with them using the optional tactic of the
 
862
{\tt Hint~Rewrite} command.
 
863
 
 
864
\firstexample
 
865
\example{Ackermann function}
 
866
%Here is a basic use of {\tt AutoRewrite} with the Ackermann function:
 
867
 
 
868
\begin{coq_example*}
 
869
Require Import Arith.
 
870
Variable Ack : 
 
871
           nat -> nat -> nat.
 
872
Axiom Ack0 : 
 
873
        forall m:nat, Ack 0 m = S m.
 
874
Axiom Ack1 : forall n:nat, Ack (S n) 0 = Ack n 1.
 
875
Axiom Ack2 : forall n m:nat, Ack (S n) (S m) = Ack n (Ack (S n) m).
 
876
\end{coq_example*}
 
877
 
 
878
\begin{coq_example}
 
879
Hint Rewrite Ack0 Ack1 Ack2 : base0.
 
880
Lemma ResAck0 : 
 
881
 Ack 3 2 = 29.
 
882
autorewrite with base0 using try reflexivity.
 
883
\end{coq_example}
 
884
 
 
885
\begin{coq_eval}
 
886
Reset Initial.
 
887
\end{coq_eval}
 
888
 
 
889
\example{Mac Carthy function}
 
890
%The Mac Carthy function shows a more complex case:
 
891
 
 
892
\begin{coq_example*}
 
893
Require Import Omega.
 
894
Variable g :   
 
895
           nat -> nat -> nat.
 
896
Axiom g0 : 
 
897
        forall m:nat, g 0 m = m.
 
898
Axiom
 
899
  g1 :
 
900
    forall n m:nat,
 
901
      (n > 0) -> (m > 100) -> g n m = g (pred n) (m - 10).
 
902
Axiom
 
903
  g2 :
 
904
    forall n m:nat,
 
905
      (n > 0) -> (m <= 100) -> g n m = g (S n) (m + 11).
 
906
\end{coq_example*}
 
907
 
 
908
\begin{coq_example}
 
909
Hint Rewrite g0 g1 g2 using omega : base1.
 
910
Lemma Resg0 : 
 
911
 g 1 110 = 100.
 
912
autorewrite with base1 using reflexivity || simpl.
 
913
\end{coq_example}
 
914
 
 
915
\begin{coq_eval}
 
916
Abort.
 
917
\end{coq_eval}
 
918
 
 
919
\begin{coq_example}
 
920
Lemma Resg1 : g 1 95 = 91.
 
921
autorewrite with base1 using reflexivity || simpl.
 
922
\end{coq_example}
 
923
 
 
924
\begin{coq_eval}
 
925
Reset Initial.
 
926
\end{coq_eval}
 
927
 
 
928
\section[\tt quote]{\tt quote\tacindex{quote}
 
929
\label{quote-examples}}
 
930
 
 
931
The tactic \texttt{quote} allows to use Barendregt's so-called
 
932
2-level approach without writing any ML code. Suppose you have a
 
933
language \texttt{L} of 
 
934
'abstract terms' and a type \texttt{A} of 'concrete terms' 
 
935
and a function \texttt{f : L -> A}. If \texttt{L} is a simple
 
936
inductive datatype and \texttt{f} a simple fixpoint, \texttt{quote f}
 
937
will replace the head of current goal by a convertible term of the form 
 
938
\texttt{(f t)}. \texttt{L} must have a constructor of type: \texttt{A
 
939
  -> L}. 
 
940
 
 
941
Here is an example:
 
942
 
 
943
\begin{coq_example}
 
944
Require Import Quote.
 
945
Parameters A B C : Prop.
 
946
Inductive formula : Type :=
 
947
  | f_and : formula -> formula -> formula (* binary constructor *)
 
948
  | f_or : formula -> formula -> formula
 
949
  | f_not : formula -> formula (* unary constructor *)
 
950
  | f_true : formula (* 0-ary constructor *)
 
951
  | f_const : Prop -> formula (* contructor for constants *).
 
952
Fixpoint interp_f (f:
 
953
                   formula) : Prop :=
 
954
  match f with
 
955
  | f_and f1 f2 => interp_f f1 /\ interp_f f2
 
956
  | f_or f1 f2 => interp_f f1 \/ interp_f f2
 
957
  | f_not f1 => ~ interp_f f1
 
958
  | f_true => True
 
959
  | f_const c => c
 
960
  end.
 
961
Goal A /\ (A \/ True) /\ ~ B /\ (A <-> A).
 
962
quote interp_f.
 
963
\end{coq_example}
 
964
 
 
965
The algorithm to perform this inversion is: try to match the
 
966
term with right-hand sides expression of \texttt{f}. If there is a
 
967
match, apply the corresponding left-hand side and call yourself
 
968
recursively on sub-terms. If there is no match, we are at a leaf:
 
969
return the corresponding constructor (here \texttt{f\_const}) applied
 
970
to the term. 
 
971
 
 
972
\begin{ErrMsgs}
 
973
\item \errindex{quote: not a simple fixpoint} \\
 
974
  Happens when \texttt{quote} is not able to perform inversion properly.
 
975
\end{ErrMsgs}
 
976
 
 
977
\subsection{Introducing variables map}
 
978
 
 
979
The normal use of \texttt{quote} is to make proofs by reflection: one
 
980
defines a function \texttt{simplify : formula -> formula} and proves a 
 
981
theorem \texttt{simplify\_ok: (f:formula)(interp\_f (simplify f)) ->
 
982
  (interp\_f f)}. Then, one can simplify formulas by doing:
 
983
\begin{verbatim}
 
984
   quote interp_f.
 
985
   apply simplify_ok.
 
986
   compute.
 
987
\end{verbatim}
 
988
But there is a problem with leafs: in the example above one cannot
 
989
write a function that implements, for example, the logical simplifications 
 
990
$A \land A \ra A$ or $A \land \lnot A \ra \texttt{False}$. This is
 
991
because the \Prop{} is impredicative.
 
992
 
 
993
It is better to use that type of formulas:
 
994
 
 
995
\begin{coq_eval}
 
996
Reset formula.
 
997
\end{coq_eval}
 
998
\begin{coq_example}
 
999
Inductive formula : Set :=
 
1000
  | f_and : formula -> formula -> formula
 
1001
  | f_or : formula -> formula -> formula
 
1002
  | f_not : formula -> formula
 
1003
  | f_true : formula
 
1004
  | f_atom : index -> formula.
 
1005
\end{coq_example*}
 
1006
 
 
1007
\texttt{index} is defined in module \texttt{quote}. Equality on that
 
1008
type is decidable so we are able to simplify $A \land A$ into $A$ at
 
1009
the abstract level. 
 
1010
 
 
1011
When there are variables, there are bindings, and \texttt{quote}
 
1012
provides also a type \texttt{(varmap A)} of bindings from
 
1013
\texttt{index} to any set \texttt{A}, and a function
 
1014
\texttt{varmap\_find} to search in such maps. The interpretation
 
1015
function has now another argument, a variables map:
 
1016
 
 
1017
\begin{coq_example}
 
1018
Fixpoint interp_f (vm:
 
1019
                    varmap Prop) (f:formula) {struct f} : Prop :=
 
1020
  match f with
 
1021
  | f_and f1 f2 => interp_f vm f1 /\ interp_f vm f2
 
1022
  | f_or f1 f2 => interp_f vm f1 \/ interp_f vm f2
 
1023
  | f_not f1 => ~ interp_f vm f1
 
1024
  | f_true => True
 
1025
  | f_atom i => varmap_find True i vm
 
1026
  end.
 
1027
\end{coq_example}
 
1028
 
 
1029
\noindent\texttt{quote} handles this second case properly:
 
1030
 
 
1031
\begin{coq_example}
 
1032
Goal A /\ (B \/ A) /\ (A \/ ~ B).
 
1033
quote interp_f.
 
1034
\end{coq_example}
 
1035
 
 
1036
It builds \texttt{vm} and \texttt{t} such that \texttt{(f vm t)} is
 
1037
convertible with the conclusion of current goal.
 
1038
 
 
1039
\subsection{Combining variables and constants}
 
1040
 
 
1041
One can have both variables and constants in abstracts terms; that is
 
1042
the case, for example, for the \texttt{ring} tactic (chapter
 
1043
\ref{ring}). Then one must provide to \texttt{quote} a list of
 
1044
\emph{constructors of constants}. For example, if the list is
 
1045
\texttt{[O S]} then closed natural numbers will be considered as
 
1046
constants and other terms as variables. 
 
1047
 
 
1048
Example: 
 
1049
 
 
1050
\begin{coq_eval}
 
1051
Reset formula.
 
1052
\end{coq_eval}
 
1053
\begin{coq_example*}
 
1054
Inductive formula : Type :=
 
1055
  | f_and : formula -> formula -> formula
 
1056
  | f_or : formula -> formula -> formula
 
1057
  | f_not : formula -> formula
 
1058
  | f_true : formula
 
1059
  | f_const : Prop -> formula (* constructor for constants *)
 
1060
  | f_atom : index -> formula.
 
1061
Fixpoint interp_f
 
1062
 (vm:            (* constructor for variables *)
 
1063
  varmap Prop) (f:formula) {struct f} : Prop :=
 
1064
  match f with
 
1065
  | f_and f1 f2 => interp_f vm f1 /\ interp_f vm f2
 
1066
  | f_or f1 f2 => interp_f vm f1 \/ interp_f vm f2
 
1067
  | f_not f1 => ~ interp_f vm f1
 
1068
  | f_true => True
 
1069
  | f_const c => c
 
1070
  | f_atom i => varmap_find True i vm
 
1071
  end.
 
1072
Goal 
 
1073
A /\ (A \/ True) /\ ~ B /\ (C <-> C).
 
1074
\end{coq_example*}
 
1075
 
 
1076
\begin{coq_example}
 
1077
quote interp_f [ A B ].
 
1078
Undo.
 
1079
  quote interp_f [ B C iff ].
 
1080
\end{coq_example}
 
1081
 
 
1082
\Warning Since function inversion
 
1083
is undecidable in general case, don't expect miracles from it!
 
1084
 
 
1085
% \SeeAlso file \texttt{theories/DEMOS/DemoQuote.v}
 
1086
 
 
1087
\SeeAlso comments of source file \texttt{tactics/contrib/polynom/quote.ml}
 
1088
 
 
1089
\SeeAlso the \texttt{ring} tactic (Chapter~\ref{ring})
 
1090
 
 
1091
 
 
1092
 
 
1093
\section{Using the tactical language}
 
1094
 
 
1095
\subsection{About the cardinality of the set of natural numbers}
 
1096
 
 
1097
A first example which shows how to use the pattern matching over the proof
 
1098
contexts is the proof that natural numbers have more than two elements. The
 
1099
proof of such a lemma can be done as %shown on Figure~\ref{cnatltac}.
 
1100
follows:
 
1101
%\begin{figure}
 
1102
%\begin{centerframe}
 
1103
\begin{coq_eval}
 
1104
Reset Initial.
 
1105
Require Import Arith.
 
1106
Require Import List.
 
1107
\end{coq_eval}
 
1108
\begin{coq_example*}
 
1109
Lemma card_nat :
 
1110
 ~ (exists x : nat, exists y : nat, forall z:nat, x = z \/ y = z).
 
1111
Proof.
 
1112
red; intros (x, (y, Hy)).
 
1113
elim (Hy 0); elim (Hy 1); elim (Hy 2); intros;
 
1114
 match goal with
 
1115
 | [_:(?a = ?b),_:(?a = ?c) |- _ ] =>
 
1116
     cut (b = c); [ discriminate | apply trans_equal with a; auto ]
 
1117
 end.
 
1118
Qed.
 
1119
\end{coq_example*}
 
1120
%\end{centerframe}
 
1121
%\caption{A proof on cardinality of natural numbers}
 
1122
%\label{cnatltac}
 
1123
%\end{figure}
 
1124
 
 
1125
We can notice that all the (very similar) cases coming from the three
 
1126
eliminations (with three distinct natural numbers) are successfully solved by
 
1127
a {\tt match goal} structure and, in particular, with only one pattern (use
 
1128
of non-linear matching).
 
1129
 
 
1130
\subsection{Permutation on closed lists}
 
1131
 
 
1132
Another more complex example is the problem of permutation on closed lists. The
 
1133
aim is to show that a closed list is a permutation of another one.
 
1134
 
 
1135
First, we define the permutation predicate as shown in table~\ref{permutpred}.
 
1136
 
 
1137
\begin{figure}
 
1138
\begin{centerframe}
 
1139
\begin{coq_example*}
 
1140
Section Sort.
 
1141
Variable A : Set.
 
1142
Inductive permut : list A -> list A -> Prop :=
 
1143
  | permut_refl   : forall l, permut l l
 
1144
  | permut_cons   :
 
1145
      forall a l0 l1, permut l0 l1 -> permut (a :: l0) (a :: l1)
 
1146
  | permut_append : forall a l, permut (a :: l) (l ++ a :: nil)
 
1147
  | permut_trans  :
 
1148
      forall l0 l1 l2, permut l0 l1 -> permut l1 l2 -> permut l0 l2.
 
1149
End Sort.
 
1150
\end{coq_example*}
 
1151
\end{centerframe}
 
1152
\caption{Definition of the permutation predicate}
 
1153
\label{permutpred}
 
1154
\end{figure}
 
1155
 
 
1156
A more complex example is the problem of permutation on closed lists.
 
1157
The aim is to show that a closed list is a permutation of another one.
 
1158
First, we define the permutation predicate as shown on
 
1159
Figure~\ref{permutpred}.
 
1160
 
 
1161
\begin{figure}
 
1162
\begin{centerframe}
 
1163
\begin{coq_example}
 
1164
Ltac Permut n :=
 
1165
  match goal with
 
1166
  | |- (permut _ ?l ?l) => apply permut_refl
 
1167
  | |- (permut _ (?a :: ?l1) (?a :: ?l2)) =>
 
1168
      let newn := eval compute in (length l1) in
 
1169
      (apply permut_cons; Permut newn)
 
1170
  | |- (permut ?A (?a :: ?l1) ?l2) =>
 
1171
      match eval compute in n with
 
1172
      | 1 => fail
 
1173
      | _ =>
 
1174
          let l1' := constr:(l1 ++ a :: nil) in
 
1175
          (apply (permut_trans A (a :: l1) l1' l2);
 
1176
            [ apply permut_append | compute; Permut (pred n) ])
 
1177
      end
 
1178
  end.
 
1179
Ltac PermutProve :=
 
1180
  match goal with
 
1181
  | |- (permut _ ?l1 ?l2) =>
 
1182
      match eval compute in (length l1 = length l2) with
 
1183
      | (?n = ?n) => Permut n
 
1184
      end
 
1185
  end.
 
1186
\end{coq_example}
 
1187
\end{centerframe}
 
1188
\caption{Permutation tactic}
 
1189
\label{permutltac}
 
1190
\end{figure}
 
1191
 
 
1192
Next, we can write naturally the tactic and the result can be seen on
 
1193
Figure~\ref{permutltac}. We can notice that we use two toplevel
 
1194
definitions {\tt PermutProve} and {\tt Permut}. The function to be
 
1195
called is {\tt PermutProve} which computes the lengths of the two
 
1196
lists and calls {\tt Permut} with the length if the two lists have the
 
1197
same length. {\tt Permut} works as expected.  If the two lists are
 
1198
equal, it concludes. Otherwise, if the lists have identical first
 
1199
elements, it applies {\tt Permut} on the tail of the lists.  Finally,
 
1200
if the lists have different first elements, it puts the first element
 
1201
of one of the lists (here the second one which appears in the {\tt
 
1202
  permut} predicate) at the end if that is possible, i.e., if the new
 
1203
first element has been at this place previously. To verify that all
 
1204
rotations have been done for a list, we use the length of the list as
 
1205
an argument for {\tt Permut} and this length is decremented for each
 
1206
rotation down to, but not including, 1 because for a list of length
 
1207
$n$, we can make exactly $n-1$ rotations to generate at most $n$
 
1208
distinct lists. Here, it must be noticed that we use the natural
 
1209
numbers of {\Coq} for the rotation counter. On Figure~\ref{ltac}, we
 
1210
can see that it is possible to use usual natural numbers but they are
 
1211
only used as arguments for primitive tactics and they cannot be
 
1212
handled, in particular, we cannot make computations with them. So, a
 
1213
natural choice is to use {\Coq} data structures so that {\Coq} makes
 
1214
the computations (reductions) by {\tt eval compute in} and we can get
 
1215
the terms back by {\tt match}.
 
1216
 
 
1217
With {\tt PermutProve}, we can now prove lemmas as 
 
1218
% shown on Figure~\ref{permutlem}.
 
1219
follows:
 
1220
%\begin{figure}
 
1221
%\begin{centerframe}
 
1222
 
 
1223
\begin{coq_example*}
 
1224
Lemma permut_ex1 :
 
1225
  permut nat (1 :: 2 :: 3 :: nil) (3 :: 2 :: 1 :: nil).
 
1226
Proof. PermutProve. Qed.
 
1227
Lemma permut_ex2 :
 
1228
  permut nat
 
1229
    (0 :: 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: 9 :: nil)
 
1230
    (0 :: 2 :: 4 :: 6 :: 8 :: 9 :: 7 :: 5 :: 3 :: 1 :: nil).
 
1231
Proof. PermutProve. Qed.
 
1232
\end{coq_example*}
 
1233
%\end{centerframe}
 
1234
%\caption{Examples of {\tt PermutProve} use}
 
1235
%\label{permutlem}
 
1236
%\end{figure}
 
1237
 
 
1238
 
 
1239
\subsection{Deciding intuitionistic propositional logic}
 
1240
 
 
1241
\begin{figure}[b]
 
1242
\begin{centerframe}
 
1243
\begin{coq_example}
 
1244
Ltac Axioms :=
 
1245
  match goal with
 
1246
  | |- True => trivial
 
1247
  | _:False |- _  => elimtype False; assumption
 
1248
  | _:?A |- ?A  => auto
 
1249
  end.
 
1250
\end{coq_example}
 
1251
\end{centerframe}
 
1252
\caption{Deciding intuitionistic propositions (1)}
 
1253
\label{tautoltaca}
 
1254
\end{figure}
 
1255
 
 
1256
 
 
1257
\begin{figure}
 
1258
\begin{centerframe}
 
1259
\begin{coq_example}
 
1260
Ltac DSimplif :=
 
1261
  repeat
 
1262
   (intros;
 
1263
    match goal with
 
1264
     | id:(~ _) |- _ => red in id
 
1265
     | id:(_ /\ _) |- _ =>
 
1266
         elim id; do 2 intro; clear id
 
1267
     | id:(_ \/ _) |- _ =>
 
1268
         elim id; intro; clear id
 
1269
     | id:(?A /\ ?B -> ?C) |- _ =>
 
1270
         cut (A -> B -> C);
 
1271
          [ intro | intros; apply id; split; assumption ]
 
1272
     | id:(?A \/ ?B -> ?C) |- _ =>
 
1273
         cut (B -> C);
 
1274
          [ cut (A -> C);
 
1275
             [ intros; clear id
 
1276
             | intro; apply id; left; assumption ]
 
1277
          | intro; apply id; right; assumption ]
 
1278
     | id0:(?A -> ?B),id1:?A |- _ =>
 
1279
         cut B; [ intro; clear id0 | apply id0; assumption ]
 
1280
     | |- (_ /\ _) => split
 
1281
     | |- (~ _) => red
 
1282
     end).
 
1283
Ltac TautoProp :=
 
1284
  DSimplif;
 
1285
   Axioms ||
 
1286
     match goal with
 
1287
     | id:((?A -> ?B) -> ?C) |- _ =>
 
1288
          cut (B -> C);
 
1289
          [ intro; cut (A -> B);
 
1290
             [ intro; cut C;
 
1291
                [ intro; clear id | apply id; assumption ]
 
1292
             | clear id ]
 
1293
          | intro; apply id; intro; assumption ]; TautoProp
 
1294
     | id:(~ ?A -> ?B) |- _ =>
 
1295
         cut (False -> B);
 
1296
          [ intro; cut (A -> False);
 
1297
             [ intro; cut B;
 
1298
                [ intro; clear id | apply id; assumption ]
 
1299
             | clear id ]
 
1300
          | intro; apply id; red; intro; assumption ]; TautoProp
 
1301
     | |- (_ \/ _) => (left; TautoProp) || (right; TautoProp)
 
1302
     end.
 
1303
\end{coq_example}
 
1304
\end{centerframe}
 
1305
\caption{Deciding intuitionistic propositions (2)}
 
1306
\label{tautoltacb}
 
1307
\end{figure}
 
1308
 
 
1309
The pattern matching on goals allows a complete and so a powerful
 
1310
backtracking when returning tactic values. An interesting application
 
1311
is the problem of deciding intuitionistic propositional logic.
 
1312
Considering the contraction-free sequent calculi {\tt LJT*} of
 
1313
Roy~Dyckhoff (\cite{Dyc92}), it is quite natural to code such a tactic
 
1314
using the tactic language as shown on Figures~\ref{tautoltaca}
 
1315
and~\ref{tautoltacb}. The tactic {\tt Axioms} tries to conclude using
 
1316
usual axioms. The tactic {\tt DSimplif} applies all the reversible
 
1317
rules of Dyckhoff's system. Finally, the tactic {\tt TautoProp} (the
 
1318
main tactic to be called) simplifies with {\tt DSimplif}, tries to
 
1319
conclude with {\tt Axioms} and tries several paths using the
 
1320
backtracking rules (one of the four Dyckhoff's rules for the left
 
1321
implication to get rid of the contraction and the right or).
 
1322
 
 
1323
For example, with {\tt TautoProp}, we can prove tautologies like
 
1324
 those:
 
1325
% on Figure~\ref{tautolem}.
 
1326
%\begin{figure}[tbp]
 
1327
%\begin{centerframe}
 
1328
\begin{coq_example*}
 
1329
Lemma tauto_ex1 : forall A B:Prop, A /\ B -> A \/ B.
 
1330
Proof. TautoProp. Qed.
 
1331
Lemma tauto_ex2 :
 
1332
   forall A B:Prop, (~ ~ B -> B) -> (A -> B) -> ~ ~ A -> B.
 
1333
Proof. TautoProp. Qed.
 
1334
\end{coq_example*}
 
1335
%\end{centerframe}
 
1336
%\caption{Proofs of tautologies with {\tt TautoProp}}
 
1337
%\label{tautolem}
 
1338
%\end{figure}
 
1339
 
 
1340
\subsection{Deciding type isomorphisms}
 
1341
 
 
1342
A more tricky problem is to decide equalities between types and modulo
 
1343
isomorphisms. Here, we choose to use the isomorphisms of the simply typed
 
1344
$\lb{}$-calculus with Cartesian product and $unit$ type (see, for example,
 
1345
\cite{RC95}). The axioms of this $\lb{}$-calculus are given by
 
1346
table~\ref{isosax}.
 
1347
 
 
1348
\begin{figure}
 
1349
\begin{centerframe}
 
1350
\begin{coq_eval}
 
1351
Reset Initial.
 
1352
\end{coq_eval}
 
1353
\begin{coq_example*}
 
1354
Open Scope type_scope.
 
1355
Section Iso_axioms.
 
1356
Variables A B C : Set.
 
1357
Axiom Com : A * B = B * A.
 
1358
Axiom Ass : A * (B * C) = A * B * C.
 
1359
Axiom Cur : (A * B -> C) = (A -> B -> C).
 
1360
Axiom Dis : (A -> B * C) = (A -> B) * (A -> C).
 
1361
Axiom P_unit : A * unit = A.
 
1362
Axiom AR_unit : (A -> unit) = unit.
 
1363
Axiom AL_unit : (unit -> A) = A.
 
1364
Lemma Cons : B = C -> A * B = A * C.
 
1365
Proof.
 
1366
intro Heq; rewrite Heq; apply refl_equal.
 
1367
Qed.
 
1368
End Iso_axioms.
 
1369
\end{coq_example*}
 
1370
\end{centerframe}
 
1371
\caption{Type isomorphism axioms}
 
1372
\label{isosax}
 
1373
\end{figure}
 
1374
 
 
1375
A more tricky problem is to decide equalities between types and modulo
 
1376
isomorphisms. Here, we choose to use the isomorphisms of the simply typed
 
1377
$\lb{}$-calculus with Cartesian product and $unit$ type (see, for example,
 
1378
\cite{RC95}). The axioms of this $\lb{}$-calculus are given on
 
1379
Figure~\ref{isosax}.
 
1380
 
 
1381
\begin{figure}[ht]
 
1382
\begin{centerframe}
 
1383
\begin{coq_example}
 
1384
Ltac DSimplif trm :=
 
1385
  match trm with
 
1386
  | (?A * ?B * ?C) =>
 
1387
      rewrite <- (Ass A B C); try MainSimplif
 
1388
  | (?A * ?B -> ?C) =>
 
1389
      rewrite (Cur A B C); try MainSimplif
 
1390
  | (?A -> ?B * ?C) =>
 
1391
      rewrite (Dis A B C); try MainSimplif
 
1392
  | (?A * unit) =>
 
1393
      rewrite (P_unit A); try MainSimplif
 
1394
  | (unit * ?B) =>
 
1395
      rewrite (Com unit B); try MainSimplif
 
1396
  | (?A -> unit) =>
 
1397
      rewrite (AR_unit A); try MainSimplif
 
1398
  | (unit -> ?B) =>
 
1399
      rewrite (AL_unit B); try MainSimplif
 
1400
  | (?A * ?B) =>
 
1401
      (DSimplif A; try MainSimplif) || (DSimplif B; try MainSimplif)
 
1402
  | (?A -> ?B) =>
 
1403
      (DSimplif A; try MainSimplif) || (DSimplif B; try MainSimplif)
 
1404
  end
 
1405
 with MainSimplif :=
 
1406
  match goal with
 
1407
  | |- (?A = ?B) => try DSimplif A; try DSimplif B
 
1408
  end.
 
1409
Ltac Length trm :=
 
1410
  match trm with
 
1411
  | (_ * ?B) => let succ := Length B in constr:(S succ)
 
1412
  | _ => constr:1
 
1413
  end.
 
1414
Ltac assoc := repeat rewrite <- Ass.
 
1415
\end{coq_example}
 
1416
\end{centerframe}
 
1417
\caption{Type isomorphism tactic (1)}
 
1418
\label{isosltac1}
 
1419
\end{figure}
 
1420
 
 
1421
\begin{figure}[ht]
 
1422
\begin{centerframe}
 
1423
\begin{coq_example}
 
1424
Ltac DoCompare n :=
 
1425
  match goal with
 
1426
  | [ |- (?A = ?A) ] => apply refl_equal
 
1427
  | [ |- (?A * ?B = ?A * ?C) ] =>
 
1428
      apply Cons; let newn := Length B in
 
1429
                  DoCompare newn
 
1430
  | [ |- (?A * ?B = ?C) ] =>
 
1431
      match eval compute in n with
 
1432
      | 1 => fail
 
1433
      | _ =>
 
1434
          pattern (A * B) at 1; rewrite Com; assoc; DoCompare (pred n)
 
1435
      end
 
1436
  end.
 
1437
Ltac CompareStruct :=
 
1438
  match goal with
 
1439
  | [ |- (?A = ?B) ] =>
 
1440
      let l1 := Length A
 
1441
      with l2 := Length B in
 
1442
      match eval compute in (l1 = l2) with
 
1443
      | (?n = ?n) => DoCompare n
 
1444
      end
 
1445
  end.
 
1446
Ltac IsoProve := MainSimplif; CompareStruct.
 
1447
\end{coq_example}
 
1448
\end{centerframe}
 
1449
\caption{Type isomorphism tactic (2)}
 
1450
\label{isosltac2}
 
1451
\end{figure}
 
1452
 
 
1453
The tactic to judge equalities modulo this axiomatization can be written as
 
1454
shown on Figures~\ref{isosltac1} and~\ref{isosltac2}. The algorithm is quite
 
1455
simple. Types are reduced using axioms that can be oriented (this done by {\tt
 
1456
MainSimplif}). The normal forms are sequences of Cartesian
 
1457
products without Cartesian product in the left component. These normal forms
 
1458
are then compared modulo permutation of the components (this is done by {\tt
 
1459
CompareStruct}). The main tactic to be called and realizing this algorithm is
 
1460
{\tt IsoProve}.
 
1461
 
 
1462
% Figure~\ref{isoslem} gives 
 
1463
Here are examples of what can be solved by {\tt IsoProve}.
 
1464
%\begin{figure}[ht]
 
1465
%\begin{centerframe}
 
1466
\begin{coq_example*}
 
1467
Lemma isos_ex1 : 
 
1468
  forall A B:Set, A * unit * B = B * (unit * A).
 
1469
Proof.
 
1470
intros; IsoProve.
 
1471
Qed.
 
1472
 
 
1473
Lemma isos_ex2 :
 
1474
  forall A B C:Set,
 
1475
    (A * unit -> B * (C * unit)) =
 
1476
    (A * unit -> (C -> unit) * C) * (unit -> A -> B).
 
1477
Proof.
 
1478
intros; IsoProve.
 
1479
Qed.
 
1480
\end{coq_example*}
 
1481
%\end{centerframe}
 
1482
%\caption{Type equalities solved by {\tt IsoProve}}
 
1483
%\label{isoslem}
 
1484
%\end{figure}
 
1485
 
 
1486
%%% Local Variables: 
 
1487
%%% mode: latex
 
1488
%%% TeX-master: "Reference-Manual"
 
1489
%%% End: