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

« back to all changes in this revision

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