1
(***********************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
4
(* \VV/ *************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(***********************************************************************)
9
(* $Id: OrderedType.v 11700 2008-12-18 11:49:10Z letouzey $ *)
11
Require Export SetoidList.
12
Set Implicit Arguments.
13
Unset Strict Implicit.
15
(** * Ordered types *)
17
Inductive Compare (X : Type) (lt eq : X -> X -> Prop) (x y : X) : Type :=
18
| LT : lt x y -> Compare lt eq x y
19
| EQ : eq x y -> Compare lt eq x y
20
| GT : lt y x -> Compare lt eq x y.
22
Module Type MiniOrderedType.
24
Parameter Inline t : Type.
26
Parameter Inline eq : t -> t -> Prop.
27
Parameter Inline lt : t -> t -> Prop.
29
Axiom eq_refl : forall x : t, eq x x.
30
Axiom eq_sym : forall x y : t, eq x y -> eq y x.
31
Axiom eq_trans : forall x y z : t, eq x y -> eq y z -> eq x z.
33
Axiom lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z.
34
Axiom lt_not_eq : forall x y : t, lt x y -> ~ eq x y.
36
Parameter compare : forall x y : t, Compare lt eq x y.
38
Hint Immediate eq_sym.
39
Hint Resolve eq_refl eq_trans lt_not_eq lt_trans.
43
Module Type OrderedType.
44
Include Type MiniOrderedType.
46
(** A [eq_dec] can be deduced from [compare] below. But adding this
47
redundant field allows to see an OrderedType as a DecidableType. *)
48
Parameter eq_dec : forall x y, { eq x y } + { ~ eq x y }.
52
Module MOT_to_OT (Import O : MiniOrderedType) <: OrderedType.
55
Definition eq_dec : forall x y : t, {eq x y} + {~ eq x y}.
57
intros; elim (compare x y); intro H; [ right | left | right ]; auto.
58
assert (~ eq y x); auto.
63
(** * Ordered types properties *)
65
(** Additional properties that can be derived from signature
68
Module OrderedTypeFacts (Import O: OrderedType).
70
Lemma lt_antirefl : forall x, ~ lt x x.
72
intros; intro; absurd (eq x x); auto.
75
Lemma lt_eq : forall x y z, lt x y -> eq y z -> lt x z.
77
intros; destruct (compare x z); auto.
78
elim (lt_not_eq H); apply eq_trans with z; auto.
79
elim (lt_not_eq (lt_trans l H)); auto.
82
Lemma eq_lt : forall x y z, eq x y -> lt y z -> lt x z.
84
intros; destruct (compare x z); auto.
85
elim (lt_not_eq H0); apply eq_trans with x; auto.
86
elim (lt_not_eq (lt_trans H0 l)); auto.
89
Lemma le_eq : forall x y z, ~lt x y -> eq y z -> ~lt x z.
91
intros; intro; destruct H; apply lt_eq with z; auto.
94
Lemma eq_le : forall x y z, eq x y -> ~lt y z -> ~lt x z.
96
intros; intro; destruct H0; apply eq_lt with x; auto.
99
Lemma neq_eq : forall x y z, ~eq x y -> eq y z -> ~eq x z.
101
intros; intro; destruct H; apply eq_trans with z; auto.
104
Lemma eq_neq : forall x y z, eq x y -> ~eq y z -> ~eq x z.
106
intros; intro; destruct H0; apply eq_trans with x; auto.
109
Hint Immediate eq_lt lt_eq le_eq eq_le neq_eq eq_neq.
111
Lemma le_lt_trans : forall x y z, ~lt y x -> lt y z -> lt x z.
113
intros; destruct (compare y x); auto.
115
apply eq_lt with y; auto.
116
apply lt_trans with y; auto.
119
Lemma lt_le_trans : forall x y z, lt x y -> ~lt z y -> lt x z.
121
intros; destruct (compare z y); auto.
123
apply lt_eq with y; auto.
124
apply lt_trans with y; auto.
127
Lemma le_neq : forall x y, ~lt x y -> ~eq x y -> lt y x.
129
intros; destruct (compare x y); intuition.
132
Lemma neq_sym : forall x y, ~eq x y -> ~eq y x.
137
(* TODO concernant la tactique order:
138
* propagate_lt n'est sans doute pas complet
140
* exploiter les hypotheses negatives restant a la fin
141
* faire que ca marche meme quand une hypothese depend d'un eq ou lt.
144
Ltac abstraction := match goal with
145
(* First, some obvious simplifications *)
146
| H : False |- _ => elim H
147
| H : lt ?x ?x |- _ => elim (lt_antirefl H)
148
| H : ~eq ?x ?x |- _ => elim (H (eq_refl x))
149
| H : eq ?x ?x |- _ => clear H; abstraction
150
| H : ~lt ?x ?x |- _ => clear H; abstraction
151
| |- eq ?x ?x => exact (eq_refl x)
152
| |- lt ?x ?x => elimtype False; abstraction
153
| |- ~ _ => intro; abstraction
154
| H1: ~lt ?x ?y, H2: ~eq ?x ?y |- _ =>
155
generalize (le_neq H1 H2); clear H1 H2; intro; abstraction
156
| H1: ~lt ?x ?y, H2: ~eq ?y ?x |- _ =>
157
generalize (le_neq H1 (neq_sym H2)); clear H1 H2; intro; abstraction
158
(* Then, we generalize all interesting facts *)
159
| H : ~eq ?x ?y |- _ => revert H; abstraction
160
| H : ~lt ?x ?y |- _ => revert H; abstraction
161
| H : lt ?x ?y |- _ => revert H; abstraction
162
| H : eq ?x ?y |- _ => revert H; abstraction
166
Ltac do_eq a b EQ := match goal with
167
| |- lt ?x ?y -> _ => let H := fresh "H" in
169
(generalize (eq_lt (eq_sym EQ) H); clear H; intro H) ||
170
(generalize (lt_eq H EQ); clear H; intro H) ||
173
| |- ~lt ?x ?y -> _ => let H := fresh "H" in
175
(generalize (eq_le (eq_sym EQ) H); clear H; intro H) ||
176
(generalize (le_eq H EQ); clear H; intro H) ||
179
| |- eq ?x ?y -> _ => let H := fresh "H" in
181
(generalize (eq_trans (eq_sym EQ) H); clear H; intro H) ||
182
(generalize (eq_trans H EQ); clear H; intro H) ||
185
| |- ~eq ?x ?y -> _ => let H := fresh "H" in
187
(generalize (eq_neq (eq_sym EQ) H); clear H; intro H) ||
188
(generalize (neq_eq H EQ); clear H; intro H) ||
191
| |- lt a ?y => apply eq_lt with b; [exact EQ|]
192
| |- lt ?y a => apply lt_eq with b; [|exact (eq_sym EQ)]
193
| |- eq a ?y => apply eq_trans with b; [exact EQ|]
194
| |- eq ?y a => apply eq_trans with b; [|exact (eq_sym EQ)]
198
Ltac propagate_eq := abstraction; clear; match goal with
199
(* the abstraction tactic leaves equality facts in head position...*)
200
| |- eq ?a ?b -> _ =>
201
let EQ := fresh "EQ" in (intro EQ; do_eq a b EQ; clear EQ);
206
Ltac do_lt x y LT := match goal with
208
| |- lt x y -> _ => intros _; do_lt x y LT
209
| |- lt y ?z -> _ => let H := fresh "H" in
210
(intro H; generalize (lt_trans LT H); intro); do_lt x y LT
211
| |- lt ?z x -> _ => let H := fresh "H" in
212
(intro H; generalize (lt_trans H LT); intro); do_lt x y LT
213
| |- lt _ _ -> _ => intro; do_lt x y LT
215
| |- ~lt y x -> _ => intros _; do_lt x y LT
216
| |- ~lt x ?z -> _ => let H := fresh "H" in
217
(intro H; generalize (le_lt_trans H LT); intro); do_lt x y LT
218
| |- ~lt ?z y -> _ => let H := fresh "H" in
219
(intro H; generalize (lt_le_trans LT H); intro); do_lt x y LT
220
| |- ~lt _ _ -> _ => intro; do_lt x y LT
224
Definition hide_lt := lt.
226
Ltac propagate_lt := abstraction; match goal with
227
(* when no [=] remains, the abstraction tactic leaves [<] facts first. *)
228
| |- lt ?x ?y -> _ =>
229
let LT := fresh "LT" in (intro LT; do_lt x y LT;
230
change (hide_lt x y) in LT);
232
| _ => unfold hide_lt in *
243
Ltac false_order := elimtype False; order.
245
Lemma gt_not_eq : forall x y, lt y x -> ~ eq x y.
250
Lemma eq_not_lt : forall x y : t, eq x y -> ~ lt x y.
255
Hint Resolve gt_not_eq eq_not_lt.
257
Lemma eq_not_gt : forall x y : t, eq x y -> ~ lt y x.
262
Lemma lt_not_gt : forall x y : t, lt x y -> ~ lt y x.
267
Hint Resolve eq_not_gt lt_antirefl lt_not_gt.
269
Lemma elim_compare_eq :
271
eq x y -> exists H : eq x y, compare x y = EQ _ H.
273
intros; case (compare x y); intros H'; try solve [false_order].
277
Lemma elim_compare_lt :
279
lt x y -> exists H : lt x y, compare x y = LT _ H.
281
intros; case (compare x y); intros H'; try solve [false_order].
285
Lemma elim_compare_gt :
287
lt y x -> exists H : lt y x, compare x y = GT _ H.
289
intros; case (compare x y); intros H'; try solve [false_order].
295
| |- ?e => match e with
296
| context ctx [ compare ?a ?b ] =>
298
(destruct (compare a b) as [H|H|H];
299
try solve [ intros; false_order])
303
Ltac elim_comp_eq x y :=
304
elim (elim_compare_eq (x:=x) (y:=y));
305
[ intros _1 _2; rewrite _2; clear _1 _2 | auto ].
307
Ltac elim_comp_lt x y :=
308
elim (elim_compare_lt (x:=x) (y:=y));
309
[ intros _1 _2; rewrite _2; clear _1 _2 | auto ].
311
Ltac elim_comp_gt x y :=
312
elim (elim_compare_gt (x:=x) (y:=y));
313
[ intros _1 _2; rewrite _2; clear _1 _2 | auto ].
315
(** For compatibility reasons *)
316
Definition eq_dec := eq_dec.
318
Lemma lt_dec : forall x y : t, {lt x y} + {~ lt x y}.
320
intros; elim (compare x y); [ left | right | right ]; auto.
323
Definition eqb x y : bool := if eq_dec x y then true else false.
326
forall x y, eqb x y = match compare x y with EQ _ => true | _ => false end.
328
unfold eqb; intros; destruct (eq_dec x y); elim_comp; auto.
331
(* Specialization of resuts about lists modulo. *)
333
Section ForNotations.
335
Notation In:=(InA eq).
336
Notation Inf:=(lelistA lt).
337
Notation Sort:=(sort lt).
338
Notation NoDup:=(NoDupA eq).
340
Lemma In_eq : forall l x y, eq x y -> In x l -> In y l.
341
Proof. exact (InA_eqA eq_sym eq_trans). Qed.
343
Lemma ListIn_In : forall l x, List.In x l -> In x l.
344
Proof. exact (In_InA eq_refl). Qed.
346
Lemma Inf_lt : forall l x y, lt x y -> Inf y l -> Inf x l.
347
Proof. exact (InfA_ltA lt_trans). Qed.
349
Lemma Inf_eq : forall l x y, eq x y -> Inf y l -> Inf x l.
350
Proof. exact (InfA_eqA eq_lt). Qed.
352
Lemma Sort_Inf_In : forall l x a, Sort l -> Inf a l -> In x l -> lt a x.
353
Proof. exact (SortA_InfA_InA eq_refl eq_sym lt_trans lt_eq eq_lt). Qed.
355
Lemma ListIn_Inf : forall l x, (forall y, List.In y l -> lt x y) -> Inf x l.
356
Proof. exact (@In_InfA t lt). Qed.
358
Lemma In_Inf : forall l x, (forall y, In y l -> lt x y) -> Inf x l.
359
Proof. exact (InA_InfA eq_refl (ltA:=lt)). Qed.
362
forall l x, Sort l -> (Inf x l <-> (forall y, In y l -> lt x y)).
363
Proof. exact (InfA_alt eq_refl eq_sym lt_trans lt_eq eq_lt). Qed.
365
Lemma Sort_NoDup : forall l, Sort l -> NoDup l.
366
Proof. exact (SortA_NoDupA eq_refl eq_sym lt_trans lt_not_eq lt_eq eq_lt) . Qed.
370
Hint Resolve ListIn_In Sort_NoDup Inf_lt.
371
Hint Immediate In_eq Inf_lt.
373
End OrderedTypeFacts.
375
Module KeyOrderedType(O:OrderedType).
377
Module MO:=OrderedTypeFacts(O).
384
Definition eqk (p p':key*elt) := eq (fst p) (fst p').
385
Definition eqke (p p':key*elt) :=
386
eq (fst p) (fst p') /\ (snd p) = (snd p').
387
Definition ltk (p p':key*elt) := lt (fst p) (fst p').
389
Hint Unfold eqk eqke ltk.
390
Hint Extern 2 (eqke ?a ?b) => split.
392
(* eqke is stricter than eqk *)
394
Lemma eqke_eqk : forall x x', eqke x x' -> eqk x x'.
396
unfold eqk, eqke; intuition.
399
(* ltk ignore the second components *)
401
Lemma ltk_right_r : forall x k e e', ltk x (k,e) -> ltk x (k,e').
404
Lemma ltk_right_l : forall x k e e', ltk (k,e) x -> ltk (k,e') x.
406
Hint Immediate ltk_right_r ltk_right_l.
408
(* eqk, eqke are equalities, ltk is a strict order *)
410
Lemma eqk_refl : forall e, eqk e e.
413
Lemma eqke_refl : forall e, eqke e e.
416
Lemma eqk_sym : forall e e', eqk e e' -> eqk e' e.
419
Lemma eqke_sym : forall e e', eqke e e' -> eqke e' e.
420
Proof. unfold eqke; intuition. Qed.
422
Lemma eqk_trans : forall e e' e'', eqk e e' -> eqk e' e'' -> eqk e e''.
425
Lemma eqke_trans : forall e e' e'', eqke e e' -> eqke e' e'' -> eqke e e''.
427
unfold eqke; intuition; [ eauto | congruence ].
430
Lemma ltk_trans : forall e e' e'', ltk e e' -> ltk e' e'' -> ltk e e''.
433
Lemma ltk_not_eqk : forall e e', ltk e e' -> ~ eqk e e'.
434
Proof. unfold eqk, ltk; auto. Qed.
436
Lemma ltk_not_eqke : forall e e', ltk e e' -> ~eqke e e'.
438
unfold eqke, ltk; intuition; simpl in *; subst.
439
exact (lt_not_eq H H1).
442
Hint Resolve eqk_trans eqke_trans eqk_refl eqke_refl.
443
Hint Resolve ltk_trans ltk_not_eqk ltk_not_eqke.
444
Hint Immediate eqk_sym eqke_sym.
446
(* Additionnal facts *)
448
Lemma eqk_not_ltk : forall x x', eqk x x' -> ~ltk x x'.
450
unfold eqk, ltk; simpl; auto.
453
Lemma ltk_eqk : forall e e' e'', ltk e e' -> eqk e' e'' -> ltk e e''.
456
Lemma eqk_ltk : forall e e' e'', eqk e e' -> ltk e' e'' -> ltk e e''.
458
intros (k,e) (k',e') (k'',e'').
459
unfold ltk, eqk; simpl; eauto.
461
Hint Resolve eqk_not_ltk.
462
Hint Immediate ltk_eqk eqk_ltk.
465
forall x m, InA eqke x m -> InA eqk x m.
467
unfold eqke; induction 1; intuition.
469
Hint Resolve InA_eqke_eqk.
471
Definition MapsTo (k:key)(e:elt):= InA eqke (k,e).
472
Definition In k m := exists e:elt, MapsTo k e m.
473
Notation Sort := (sort ltk).
474
Notation Inf := (lelistA ltk).
476
Hint Unfold MapsTo In.
478
(* An alternative formulation for [In k l] is [exists e, InA eqk (k,e) l] *)
480
Lemma In_alt : forall k l, In k l <-> exists e, InA eqk (k,e) l.
487
destruct IHInA as [e H0].
491
Lemma MapsTo_eq : forall l x y e, eq x y -> MapsTo x e l -> MapsTo y e l.
493
intros; unfold MapsTo in *; apply InA_eqA with (x,e); eauto.
496
Lemma In_eq : forall l x y, eq x y -> In x l -> In y l.
498
destruct 2 as (e,E); exists e; eapply MapsTo_eq; eauto.
501
Lemma Inf_eq : forall l x x', eqk x x' -> Inf x' l -> Inf x l.
502
Proof. exact (InfA_eqA eqk_ltk). Qed.
504
Lemma Inf_lt : forall l x x', ltk x x' -> Inf x' l -> Inf x l.
505
Proof. exact (InfA_ltA ltk_trans). Qed.
507
Hint Immediate Inf_eq.
511
forall l p q, Sort l -> Inf q l -> InA eqk p l -> ltk q p.
513
exact (SortA_InfA_InA eqk_refl eqk_sym ltk_trans ltk_eqk eqk_ltk).
516
Lemma Sort_Inf_NotIn :
517
forall l k e, Sort l -> Inf (k,e) l -> ~In k l.
520
destruct H1 as [e' H2].
521
elim (@ltk_not_eqk (k,e) (k,e')).
522
eapply Sort_Inf_In; eauto.
526
Lemma Sort_NoDupA: forall l, Sort l -> NoDupA eqk l.
528
exact (SortA_NoDupA eqk_refl eqk_sym ltk_trans ltk_not_eqk ltk_eqk eqk_ltk).
531
Lemma Sort_In_cons_1 : forall e l e', Sort (e::l) -> InA eqk e' l -> ltk e e'.
533
inversion 1; intros; eapply Sort_Inf_In; eauto.
536
Lemma Sort_In_cons_2 : forall l e e', Sort (e::l) -> InA eqk e' (e::l) ->
537
ltk e e' \/ eqk e e'.
539
inversion_clear 2; auto.
540
left; apply Sort_In_cons_1 with l; auto.
543
Lemma Sort_In_cons_3 :
544
forall x l k e, Sort ((k,e)::l) -> In x l -> ~eq x k.
546
inversion_clear 1; red; intros.
547
destruct (Sort_Inf_NotIn H0 H1 (In_eq H2 H)).
550
Lemma In_inv : forall k k' e l, In k ((k',e) :: l) -> eq k k' \/ In k l.
553
inversion_clear H0; eauto.
554
destruct H1; simpl in *; intuition.
557
Lemma In_inv_2 : forall k k' e e' l,
558
InA eqk (k, e) ((k', e') :: l) -> ~ eq k k' -> InA eqk (k, e) l.
560
inversion_clear 1; compute in H0; intuition.
563
Lemma In_inv_3 : forall x x' l,
564
InA eqke x (x' :: l) -> ~ eqk x x' -> InA eqke x l.
566
inversion_clear 1; compute in H0; intuition.
571
Hint Unfold eqk eqke ltk.
572
Hint Extern 2 (eqke ?a ?b) => split.
573
Hint Resolve eqk_trans eqke_trans eqk_refl eqke_refl.
574
Hint Resolve ltk_trans ltk_not_eqk ltk_not_eqke.
575
Hint Immediate eqk_sym eqke_sym.
576
Hint Resolve eqk_not_ltk.
577
Hint Immediate ltk_eqk eqk_ltk.
578
Hint Resolve InA_eqke_eqk.
579
Hint Unfold MapsTo In.
580
Hint Immediate Inf_eq.
582
Hint Resolve Sort_Inf_NotIn.
583
Hint Resolve In_inv_2 In_inv_3.