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

« back to all changes in this revision

Viewing changes to theories/Classes/Morphisms.v

  • 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
(************************************************************************)
 
2
(*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *)
 
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
 
4
(*   \VV/  **************************************************************)
 
5
(*    //   *      This file is distributed under the terms of the       *)
 
6
(*         *       GNU Lesser General Public License Version 2.1        *)
 
7
(************************************************************************)
 
8
 
 
9
(* Typeclass-based morphism definition and standard, minimal instances.
 
10
 
 
11
   Author: Matthieu Sozeau
 
12
   Institution: LRI, CNRS UMR 8623 - UniversitÃcopyright Paris Sud
 
13
   91405 Orsay, France *)
 
14
 
 
15
(* $Id: Morphisms.v 12189 2009-06-15 05:08:44Z msozeau $ *)
 
16
 
 
17
Require Import Coq.Program.Basics.
 
18
Require Import Coq.Program.Tactics.
 
19
Require Import Coq.Relations.Relation_Definitions.
 
20
Require Export Coq.Classes.RelationClasses.
 
21
 
 
22
(** * Morphisms.
 
23
 
 
24
   We now turn to the definition of [Morphism] and declare standard instances. 
 
25
   These will be used by the [setoid_rewrite] tactic later. *)
 
26
 
 
27
(** A morphism on a relation [R] is an object respecting the relation (in its kernel). 
 
28
   The relation [R] will be instantiated by [respectful] and [A] by an arrow type 
 
29
   for usual morphisms. *)
 
30
 
 
31
Class Morphism {A} (R : relation A) (m : A) : Prop :=
 
32
  respect : R m m.
 
33
 
 
34
(** Respectful morphisms. *)
 
35
 
 
36
(** The fully dependent version, not used yet. *)
 
37
 
 
38
Definition respectful_hetero 
 
39
  (A B : Type) 
 
40
  (C : A -> Type) (D : B -> Type) 
 
41
  (R : A -> B -> Prop) 
 
42
  (R' : forall (x : A) (y : B), C x -> D y -> Prop) : 
 
43
    (forall x : A, C x) -> (forall x : B, D x) -> Prop := 
 
44
    fun f g => forall x y, R x y -> R' x y (f x) (g y).
 
45
 
 
46
(** The non-dependent version is an instance where we forget dependencies. *)
 
47
 
 
48
Definition respectful {A B : Type}
 
49
  (R : relation A) (R' : relation B) : relation (A -> B) :=
 
50
  Eval compute in @respectful_hetero A A (fun _ => B) (fun _ => B) R (fun _ _ => R').
 
51
 
 
52
(** Notations reminiscent of the old syntax for declaring morphisms. *)
 
53
 
 
54
Delimit Scope signature_scope with signature.
 
55
 
 
56
Arguments Scope Morphism [type_scope signature_scope].
 
57
Arguments Scope respectful [type_scope type_scope signature_scope signature_scope].
 
58
 
 
59
Module MorphismNotations.
 
60
 
 
61
  Notation " R ++> R' " := (@respectful _ _ (R%signature) (R'%signature)) 
 
62
    (right associativity, at level 55) : signature_scope.
 
63
  
 
64
  Notation " R ==> R' " := (@respectful _ _ (R%signature) (R'%signature))
 
65
    (right associativity, at level 55) : signature_scope.
 
66
  
 
67
  Notation " R --> R' " := (@respectful _ _ (inverse (R%signature)) (R'%signature))
 
68
    (right associativity, at level 55) : signature_scope.
 
69
 
 
70
End MorphismNotations.
 
71
 
 
72
Export MorphismNotations.
 
73
 
 
74
Open Local Scope signature_scope.
 
75
 
 
76
(** Dependent pointwise lifting of a relation on the range. *) 
 
77
 
 
78
Definition forall_relation {A : Type} {B : A -> Type} (sig : Π a : A, relation (B a)) : relation (Π x : A, B x) :=
 
79
  λ f g, Π a : A, sig a (f a) (g a).
 
80
 
 
81
Arguments Scope forall_relation [type_scope type_scope signature_scope].
 
82
 
 
83
(** Non-dependent pointwise lifting *)
 
84
 
 
85
Definition pointwise_relation (A : Type) {B : Type} (R : relation B) : relation (A -> B) := 
 
86
  Eval compute in forall_relation (B:=λ _, B) (λ _, R).
 
87
 
 
88
Lemma pointwise_pointwise A B (R : relation B) : 
 
89
  relation_equivalence (pointwise_relation A R) (@eq A ==> R).
 
90
Proof. intros. split. simpl_relation. firstorder. Qed.
 
91
 
 
92
(** We can build a PER on the Coq function space if we have PERs on the domain and
 
93
   codomain. *)
 
94
 
 
95
Hint Unfold Reflexive : core.
 
96
Hint Unfold Symmetric : core.
 
97
Hint Unfold Transitive : core.
 
98
 
 
99
Typeclasses Opaque respectful pointwise_relation forall_relation.
 
100
 
 
101
Program Instance respectful_per `(PER A (R : relation A), PER B (R' : relation B)) : 
 
102
  PER (R ==> R').
 
103
 
 
104
  Next Obligation.
 
105
  Proof with auto.
 
106
    assert(R x0 x0).
 
107
    transitivity y0... symmetry...
 
108
    transitivity (y x0)...
 
109
  Qed.
 
110
 
 
111
(** Subrelations induce a morphism on the identity. *)
 
112
 
 
113
Instance subrelation_id_morphism `(subrelation A R₁ R₂) : Morphism (R₁ ==> R₂) id.
 
114
Proof. firstorder. Qed.
 
115
 
 
116
(** The subrelation property goes through products as usual. *)
 
117
 
 
118
Instance morphisms_subrelation_respectful `(subl : subrelation A R₂ R₁, subr : subrelation B S₁ S₂) :
 
119
  subrelation (R₁ ==> S₁) (R₂ ==> S₂).
 
120
Proof. simpl_relation. apply subr. apply H. apply subl. apply H0. Qed.
 
121
 
 
122
(** And of course it is reflexive. *)
 
123
 
 
124
Instance morphisms_subrelation_refl : ! subrelation A R R.
 
125
Proof. simpl_relation. Qed.
 
126
 
 
127
(** [Morphism] is itself a covariant morphism for [subrelation]. *)
 
128
 
 
129
Lemma subrelation_morphism `(mor : Morphism A R₁ m, unc : Unconvertible (relation A) R₁ R₂,
 
130
  sub : subrelation A R₁ R₂) : Morphism R₂ m.
 
131
Proof.
 
132
  intros. apply sub. apply mor.
 
133
Qed.
 
134
 
 
135
Instance morphism_subrelation_morphism : 
 
136
  Morphism (subrelation ++> @eq _ ==> impl) (@Morphism A).
 
137
Proof. reduce. subst. firstorder. Qed.
 
138
 
 
139
(** We use an external tactic to manage the application of subrelation, which is otherwise
 
140
   always applicable. We allow its use only once per branch. *)
 
141
 
 
142
Inductive subrelation_done : Prop := did_subrelation : subrelation_done.
 
143
 
 
144
Inductive normalization_done : Prop := did_normalization.
 
145
 
 
146
Ltac subrelation_tac := 
 
147
  match goal with
 
148
    | [ _ : subrelation_done |- _ ] => fail 1
 
149
    | [ |- @Morphism _ _ _ ] => let H := fresh "H" in
 
150
      set(H:=did_subrelation) ; eapply @subrelation_morphism
 
151
  end.
 
152
 
 
153
Hint Extern 5 (@Morphism _ _ _) => subrelation_tac : typeclass_instances.
 
154
 
 
155
(** Essential subrelation instances for [iff], [impl] and [pointwise_relation]. *)
 
156
 
 
157
Instance iff_impl_subrelation : subrelation iff impl | 2.
 
158
Proof. firstorder. Qed.
 
159
 
 
160
Instance iff_inverse_impl_subrelation : subrelation iff (inverse impl) | 2.
 
161
Proof. firstorder. Qed.
 
162
 
 
163
Instance pointwise_subrelation {A} `(sub : subrelation B R R') :
 
164
  subrelation (pointwise_relation A R) (pointwise_relation A R') | 4.
 
165
Proof. reduce. unfold pointwise_relation in *. apply sub. apply H. Qed.
 
166
 
 
167
(** The complement of a relation conserves its morphisms. *)
 
168
 
 
169
Program Instance complement_morphism
 
170
  `(mR : Morphism (A -> A -> Prop) (RA ==> RA ==> iff) R) :
 
171
  Morphism (RA ==> RA ==> iff) (complement R).
 
172
 
 
173
  Next Obligation.
 
174
  Proof.
 
175
    unfold complement.
 
176
    pose (mR x y H x0 y0 H0).
 
177
    intuition.
 
178
  Qed.
 
179
 
 
180
(** The [inverse] too, actually the [flip] instance is a bit more general. *) 
 
181
 
 
182
Program Instance flip_morphism
 
183
  `(mor : Morphism (A -> B -> C) (RA ==> RB ==> RC) f) :
 
184
  Morphism (RB ==> RA ==> RC) (flip f).
 
185
 
 
186
  Next Obligation.
 
187
  Proof.
 
188
    apply mor ; auto.
 
189
  Qed.
 
190
 
 
191
(** Every Transitive relation gives rise to a binary morphism on [impl], 
 
192
   contravariant in the first argument, covariant in the second. *)
 
193
 
 
194
Program Instance trans_contra_co_morphism
 
195
  `(Transitive A R) : Morphism (R --> R ++> impl) R.
 
196
 
 
197
  Next Obligation.
 
198
  Proof with auto.
 
199
    transitivity x...
 
200
    transitivity x0...
 
201
  Qed.
 
202
 
 
203
(** Morphism declarations for partial applications. *)
 
204
 
 
205
Program Instance trans_contra_inv_impl_morphism
 
206
  `(Transitive A R) : Morphism (R --> inverse impl) (R x) | 3.
 
207
 
 
208
  Next Obligation.
 
209
  Proof with auto.
 
210
    transitivity y...
 
211
  Qed.
 
212
 
 
213
Program Instance trans_co_impl_morphism
 
214
  `(Transitive A R) : Morphism (R ==> impl) (R x) | 3.
 
215
 
 
216
  Next Obligation.
 
217
  Proof with auto.
 
218
    transitivity x0...
 
219
  Qed.
 
220
 
 
221
Program Instance trans_sym_co_inv_impl_morphism
 
222
  `(PER A R) : Morphism (R ==> inverse impl) (R x) | 2.
 
223
 
 
224
  Next Obligation.
 
225
  Proof with auto.
 
226
    transitivity y... symmetry...
 
227
  Qed.
 
228
 
 
229
Program Instance trans_sym_contra_impl_morphism
 
230
  `(PER A R) : Morphism (R --> impl) (R x) | 2.
 
231
 
 
232
  Next Obligation.
 
233
  Proof with auto.
 
234
    transitivity x0... symmetry...
 
235
  Qed.
 
236
 
 
237
Program Instance per_partial_app_morphism
 
238
  `(PER A R) : Morphism (R ==> iff) (R x) | 1.
 
239
 
 
240
  Next Obligation.
 
241
  Proof with auto.
 
242
    split. intros ; transitivity x0...
 
243
    intros.
 
244
    transitivity y...
 
245
    symmetry...
 
246
  Qed.
 
247
 
 
248
(** Every Transitive relation induces a morphism by "pushing" an [R x y] on the left of an [R x z] proof
 
249
   to get an [R y z] goal. *)
 
250
 
 
251
Program Instance trans_co_eq_inv_impl_morphism
 
252
  `(Transitive A R) : Morphism (R ==> (@eq A) ==> inverse impl) R | 2.
 
253
 
 
254
  Next Obligation.
 
255
  Proof with auto.
 
256
    transitivity y...
 
257
  Qed.
 
258
 
 
259
(** Every Symmetric and Transitive relation gives rise to an equivariant morphism. *)
 
260
 
 
261
Program Instance PER_morphism `(PER A R) : Morphism (R ==> R ==> iff) R | 1.
 
262
 
 
263
  Next Obligation.
 
264
  Proof with auto.
 
265
    split ; intros.
 
266
    transitivity x0... transitivity x... symmetry...
 
267
  
 
268
    transitivity y... transitivity y0... symmetry...
 
269
  Qed.
 
270
 
 
271
Lemma symmetric_equiv_inverse `(Symmetric A R) : relation_equivalence R (flip R).
 
272
Proof. firstorder. Qed.
 
273
  
 
274
Program Instance compose_morphism A B C R₀ R₁ R₂ :
 
275
  Morphism ((R₁ ==> R₂) ==> (R₀ ==> R₁) ==> (R₀ ==> R₂)) (@compose A B C).
 
276
 
 
277
  Next Obligation.
 
278
  Proof.
 
279
    simpl_relation.
 
280
    unfold compose. apply H. apply H0. apply H1.
 
281
  Qed.
 
282
 
 
283
(** Coq functions are morphisms for leibniz equality, 
 
284
   applied only if really needed. *)
 
285
 
 
286
Instance reflexive_eq_dom_reflexive (A : Type) `(Reflexive B R') :
 
287
  Reflexive (@Logic.eq A ==> R').
 
288
Proof. simpl_relation. Qed.
 
289
 
 
290
(** [respectful] is a morphism for relation equivalence. *)
 
291
 
 
292
Instance respectful_morphism : 
 
293
  Morphism (relation_equivalence ++> relation_equivalence ++> relation_equivalence) (@respectful A B).
 
294
Proof.
 
295
  reduce.
 
296
  unfold respectful, relation_equivalence, predicate_equivalence in * ; simpl in *.
 
297
  split ; intros.
 
298
  
 
299
    rewrite <- H0.
 
300
    apply H1.
 
301
    rewrite H.
 
302
    assumption.
 
303
 
 
304
    rewrite H0.
 
305
    apply H1.
 
306
    rewrite <- H.
 
307
    assumption.
 
308
Qed.
 
309
 
 
310
(** Every element in the carrier of a reflexive relation is a morphism for this relation.
 
311
   We use a proxy class for this case which is used internally to discharge reflexivity constraints.
 
312
   The [Reflexive] instance will almost always be used, but it won't apply in general to any kind of 
 
313
   [Morphism (A -> B) _ _] goal, making proof-search much slower. A cleaner solution would be to be able
 
314
   to set different priorities in different hint bases and select a particular hint database for
 
315
   resolution of a type class constraint.*) 
 
316
 
 
317
Class MorphismProxy {A} (R : relation A) (m : A) : Prop :=
 
318
  respect_proxy : R m m.
 
319
 
 
320
Instance reflexive_morphism_proxy
 
321
  `(Reflexive A R) (x : A) : MorphismProxy R x | 1.
 
322
Proof. firstorder. Qed.
 
323
 
 
324
Instance morphism_morphism_proxy
 
325
  `(Morphism A R x) : MorphismProxy R x | 2.
 
326
Proof. firstorder. Qed.
 
327
 
 
328
(** [R] is Reflexive, hence we can build the needed proof. *)
 
329
 
 
330
Lemma Reflexive_partial_app_morphism `(Morphism (A -> B) (R ==> R') m, MorphismProxy A R x) :
 
331
   Morphism R' (m x).
 
332
Proof. simpl_relation. Qed.
 
333
 
 
334
Class Params {A : Type} (of : A) (arity : nat).
 
335
 
 
336
Class PartialApplication.
 
337
 
 
338
Ltac partial_application_tactic := 
 
339
  let rec do_partial_apps H m :=
 
340
    match m with
 
341
      | ?m' ?x => eapply @Reflexive_partial_app_morphism ; [do_partial_apps H m'|clear H]
 
342
      | _ => idtac
 
343
    end
 
344
  in
 
345
  let rec do_partial H ar m :=
 
346
    match ar with
 
347
      | 0 => do_partial_apps H m
 
348
      | S ?n' => 
 
349
        match m with
 
350
          ?m' ?x => do_partial H n' m'
 
351
        end
 
352
    end
 
353
  in
 
354
  let on_morphism m :=
 
355
    let m' := fresh in head_of_constr m' m ;
 
356
    let n := fresh in evar (n:nat) ;
 
357
    let v := eval compute in n in clear n ;
 
358
    let H := fresh in
 
359
      assert(H:Params m' v) by typeclasses eauto ;
 
360
      let v' := eval compute in v in 
 
361
      do_partial H v' m
 
362
 in
 
363
  match goal with
 
364
    | [ _ : subrelation_done |- _ ] => fail 1
 
365
    | [ _ : normalization_done |- _ ] => fail 1
 
366
    | [ _ : @Params _ _ _ |- _ ] => fail 1
 
367
    | [ |- @Morphism ?T _ (?m ?x) ] => 
 
368
      match goal with 
 
369
        | [ _ : PartialApplication |- _ ] => 
 
370
          eapply @Reflexive_partial_app_morphism
 
371
        | _ => 
 
372
          on_morphism (m x) || 
 
373
            (eapply @Reflexive_partial_app_morphism ;
 
374
              [ pose Build_PartialApplication | idtac ])
 
375
      end
 
376
  end.
 
377
 
 
378
Hint Extern 4 (@Morphism _ _ _) => partial_application_tactic : typeclass_instances.
 
379
 
 
380
Lemma inverse_respectful : forall (A : Type) (R : relation A) (B : Type) (R' : relation B),
 
381
  relation_equivalence (inverse (R ==> R')) (inverse R ==> inverse R').
 
382
Proof.
 
383
  intros.
 
384
  unfold flip, respectful.
 
385
  split ; intros ; intuition.
 
386
Qed.
 
387
 
 
388
(** Special-purpose class to do normalization of signatures w.r.t. inverse. *)
 
389
 
 
390
Class Normalizes (A : Type) (m : relation A) (m' : relation A) : Prop := 
 
391
  normalizes : relation_equivalence m m'.
 
392
 
 
393
(** Current strategy: add [inverse] everywhere and reduce using [subrelation]
 
394
   afterwards. *)
 
395
 
 
396
Lemma inverse_atom A R : Normalizes A R (inverse (inverse R)).
 
397
Proof.
 
398
  firstorder.
 
399
Qed.
 
400
 
 
401
Lemma inverse_arrow `(NA : Normalizes A R (inverse R'''), NB : Normalizes B R' (inverse R'')) :
 
402
  Normalizes (A -> B) (R ==> R') (inverse (R''' ==> R'')%signature).
 
403
Proof. unfold Normalizes. intros.
 
404
  rewrite NA, NB. firstorder.
 
405
Qed.
 
406
 
 
407
Ltac inverse :=   
 
408
  match goal with
 
409
    | [ |- Normalizes _ (respectful _ _) _ ] => eapply @inverse_arrow
 
410
    | _ => eapply @inverse_atom
 
411
  end.
 
412
 
 
413
Hint Extern 1 (Normalizes _ _ _) => inverse : typeclass_instances.
 
414
 
 
415
(** Treating inverse: can't make them direct instances as we 
 
416
   need at least a [flip] present in the goal. *)
 
417
 
 
418
Lemma inverse1 `(subrelation A R' R) : subrelation (inverse (inverse R')) R.
 
419
Proof. firstorder. Qed.
 
420
 
 
421
Lemma inverse2 `(subrelation A R R') : subrelation R (inverse (inverse R')).
 
422
Proof. firstorder. Qed.
 
423
 
 
424
Hint Extern 1 (subrelation (flip _) _) => eapply @inverse1 : typeclass_instances.
 
425
Hint Extern 1 (subrelation _ (flip _)) => eapply @inverse2 : typeclass_instances.
 
426
 
 
427
(** Once we have normalized, we will apply this instance to simplify the problem. *)
 
428
 
 
429
Definition morphism_inverse_morphism `(mor : Morphism A R m) : Morphism (inverse R) m := mor.
 
430
 
 
431
Hint Extern 2 (@Morphism _ (flip _) _) => eapply @morphism_inverse_morphism : typeclass_instances.
 
432
 
 
433
(** Bootstrap !!! *)
 
434
 
 
435
Instance morphism_morphism : Morphism (relation_equivalence ==> @eq _ ==> iff) (@Morphism A).
 
436
Proof.
 
437
  simpl_relation.
 
438
  reduce in H.
 
439
  split ; red ; intros.
 
440
  setoid_rewrite <- H.
 
441
  apply H0.
 
442
  setoid_rewrite H.
 
443
  apply H0.
 
444
Qed.
 
445
 
 
446
Lemma morphism_releq_morphism `(Normalizes A R R', Morphism _ R' m) : Morphism R m.
 
447
Proof.
 
448
  intros.
 
449
 
 
450
  pose respect as r.
 
451
  pose normalizes as norm.
 
452
  setoid_rewrite norm.
 
453
  assumption.
 
454
Qed.
 
455
 
 
456
Ltac morphism_normalization := 
 
457
  match goal with
 
458
    | [ _ : subrelation_done |- _ ] => fail 1
 
459
    | [ _ : normalization_done |- _ ] => fail 1
 
460
    | [ |- @Morphism _ _ _ ] => let H := fresh "H" in
 
461
      set(H:=did_normalization) ; eapply @morphism_releq_morphism
 
462
  end.
 
463
 
 
464
Hint Extern 6 (@Morphism _ _ _) => morphism_normalization : typeclass_instances.
 
465
 
 
466
(** Every reflexive relation gives rise to a morphism, only for immediately solving goals without variables. *)
 
467
 
 
468
Lemma reflexive_morphism `{Reflexive A R} (x : A)
 
469
   : Morphism R x.
 
470
Proof. firstorder. Qed.
 
471
 
 
472
Ltac morphism_reflexive :=
 
473
  match goal with
 
474
    | [ _ : normalization_done |- _ ] => fail 1
 
475
    | [ _ : subrelation_done |- _ ] => fail 1
 
476
    | [ |- @Morphism _ _ _ ] => eapply @reflexive_morphism
 
477
  end.
 
478
 
 
479
Hint Extern 7 (@Morphism _ _ _) => morphism_reflexive : typeclass_instances.