Skip to content

Commit 0fb9f60

Browse files
split FinFun and Permutation into List and Vector (#154)
split FinFun and Permutation into List and Vector
1 parent 9adb84b commit 0fb9f60

File tree

15 files changed

+381
-355
lines changed

15 files changed

+381
-355
lines changed

.nix/rocq-overlays/stdlib-subcomponents/default.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ let
3333
"classical-logic" = [ "arith" ];
3434
"sets" = [ "classical-logic" ];
3535
"vectors" = [ "lists" ];
36-
"sorting" = [ "lia" "sets" "vectors" ];
37-
"orders-ex" = [ "strings" "sorting" ];
36+
"sorting" = [ "lia" "sets" ];
37+
"orders-ex" = [ "narith" "strings" "sorting" ];
3838
"unicode" = [ ];
3939
"primitive-int" = [ "unicode" "zarith" ];
4040
"primitive-floats" = [ "primitive-int" ];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
- in `Permutation`
2+
3+
+ Moved `Fin`-specific definitons into `FinFun`
4+
(`#154 <https://github.com/coq/stdlib/pull/154>`_,
5+
by Andres Erbsen).
6+
7+
- in `FinFun`
8+
9+
+ Split out non-`Fin`-specific definitons into `Lists.Finite`
10+
(`#154 <https://github.com/coq/stdlib/pull/154>`_,
11+
by Andres Erbsen).
12+

doc/stdlib/depends.dot

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ digraph stdlib_deps {
4242
sets -> "classical-logic";
4343
sorting -> lia;
4444
sorting -> sets;
45-
sorting -> vectors;
4645
"primitive-floats" -> "primitive-int";
4746
wellfounded -> lists;
4847
relations -> "corelib-wrapper";

doc/stdlib/index-list.html.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ through the <tt>From Stdlib Require Import</tt> command.</p>
161161
theories/Lists/ListDec.v
162162
theories/Lists/ListSet.v
163163
theories/Lists/ListTactics.v
164+
theories/Lists/Finite.v
164165
theories/Numbers/NaryFunctions.v
165166
theories/Logic/WKL.v
166167
theories/Classes/EquivDec.v

theories/All/All.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ From Stdlib Require Export Lists.ListDec.
482482
From Stdlib Require Export Lists.ListDef.
483483
From Stdlib Require Export Lists.ListSet.
484484
From Stdlib Require Export Lists.ListTactics.
485+
From Stdlib Require Export Lists.Finite.
485486
From Stdlib Require Export Init.Byte.
486487
From Stdlib Require Export Init.Datatypes.
487488
From Stdlib Require Export Init.Decimal.

theories/Lists/Finite.v

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
(************************************************************************)
2+
(* * The Rocq Prover / The Rocq Development Team *)
3+
(* v * Copyright INRIA, CNRS and contributors *)
4+
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
5+
(* \VV/ **************************************************************)
6+
(* // * This file is distributed under the terms of the *)
7+
(* * GNU Lesser General Public License Version 2.1 *)
8+
(* * (see LICENSE file for the text of the license) *)
9+
(************************************************************************)
10+
11+
(** * Functions on finite domains *)
12+
13+
(** Main result : for functions [f:A->A] with finite [A],
14+
f injective <-> f bijective <-> f surjective. *)
15+
16+
From Stdlib Require Import List ListDec.
17+
Set Implicit Arguments.
18+
19+
(** General definitions *)
20+
21+
Definition Injective {A B} (f : A->B) :=
22+
forall x y, f x = f y -> x = y.
23+
24+
Definition Surjective {A B} (f : A->B) :=
25+
forall y, exists x, f x = y.
26+
27+
Definition Bijective {A B} (f : A->B) :=
28+
exists g:B->A, (forall x, g (f x) = x) /\ (forall y, f (g y) = y).
29+
30+
(** Finiteness is defined here via exhaustive list enumeration *)
31+
32+
Definition Full {A:Type} (l:list A) := forall a:A, In a l.
33+
Definition Finite (A:Type) := exists (l:list A), Full l.
34+
35+
(** In many of the following proofs, it will be convenient to have
36+
list enumerations without duplicates. As soon as we have
37+
decidability of equality (in Prop), this is equivalent
38+
to the previous notion (s. lemma Finite_dec). *)
39+
40+
Definition Listing {A:Type} (l:list A) := NoDup l /\ Full l.
41+
Definition Finite' (A:Type) := exists (l:list A), Listing l.
42+
43+
Lemma Listing_decidable_eq {A:Type} (l:list A): Listing l -> decidable_eq A.
44+
Proof.
45+
intros (Hnodup & Hfull) a a'.
46+
now apply (NoDup_list_decidable Hnodup).
47+
Qed.
48+
49+
Lemma Finite_dec {A:Type}: Finite A /\ decidable_eq A <-> Finite' A.
50+
Proof.
51+
split.
52+
- intros ((l, Hfull) & Hdec).
53+
destruct (uniquify Hdec l) as (l' & H_nodup & H_inc).
54+
exists l'. split; trivial.
55+
intros a. apply H_inc. apply Hfull.
56+
- intros (l & Hlist).
57+
apply Listing_decidable_eq in Hlist as Heqdec.
58+
destruct Hlist as (Hnodup & Hfull).
59+
split; [ exists l | ]; assumption.
60+
Qed.
61+
62+
(* Finite_alt is a weaker version of Finite_dec and has been deprecated. *)
63+
Lemma Finite_alt_deprecated A (d:decidable_eq A) : Finite A <-> Finite' A.
64+
Proof.
65+
split.
66+
- intros F. now apply Finite_dec.
67+
- intros (l & _ & F). now exists l.
68+
Qed.
69+
#[deprecated(since="8.17", note="Use Finite_dec instead.")]
70+
Notation Finite_alt := Finite_alt_deprecated.
71+
72+
(** Injections characterized in term of lists *)
73+
74+
Lemma Injective_map_NoDup A B (f:A->B) (l:list A) :
75+
Injective f -> NoDup l -> NoDup (map f l).
76+
Proof.
77+
intros Ij. induction 1 as [|x l X N IH]; simpl; constructor; trivial.
78+
rewrite in_map_iff. intros (y & E & Y). apply Ij in E. now subst.
79+
Qed.
80+
81+
Lemma Injective_map_NoDup_in A B (f:A->B) (l:list A) :
82+
(forall x y, In x l -> In y l -> f x = f y -> x = y) -> NoDup l -> NoDup (map f l).
83+
Proof.
84+
pose proof @in_cons. pose proof @in_eq.
85+
intros Ij N; revert Ij; induction N; cbn [map]; constructor; auto.
86+
rewrite in_map_iff. intros (y & E & Y). apply Ij in E; auto; congruence.
87+
Qed.
88+
89+
Lemma Injective_list_carac A B (d:decidable_eq A)(f:A->B) :
90+
Injective f <-> (forall l, NoDup l -> NoDup (map f l)).
91+
Proof.
92+
split.
93+
- intros. now apply Injective_map_NoDup.
94+
- intros H x y E.
95+
destruct (d x y); trivial.
96+
assert (N : NoDup (x::y::nil)).
97+
{ repeat constructor; simpl; intuition. }
98+
specialize (H _ N). simpl in H. rewrite E in H.
99+
inversion_clear H; simpl in *; intuition.
100+
Qed.
101+
102+
Lemma Injective_carac A B (l:list A) : Listing l ->
103+
forall (f:A->B), Injective f <-> NoDup (map f l).
104+
Proof.
105+
intros L f. split.
106+
- intros Ij. apply Injective_map_NoDup; trivial. apply L.
107+
- intros N x y E.
108+
assert (X : In x l) by apply L.
109+
assert (Y : In y l) by apply L.
110+
apply In_nth_error in X. destruct X as (i,X).
111+
apply In_nth_error in Y. destruct Y as (j,Y).
112+
assert (X' := map_nth_error f _ _ X).
113+
assert (Y' := map_nth_error f _ _ Y).
114+
assert (i = j).
115+
{ rewrite NoDup_nth_error in N. apply N.
116+
- rewrite <- nth_error_Some. now rewrite X'.
117+
- rewrite X', Y'. now f_equal. }
118+
subst j. rewrite Y in X. now injection X.
119+
Qed.
120+
121+
(** Surjection characterized in term of lists *)
122+
123+
Lemma Surjective_list_carac A B (f:A->B):
124+
Surjective f <-> (forall lB, exists lA, incl lB (map f lA)).
125+
Proof.
126+
split.
127+
- intros Su lB.
128+
induction lB as [|b lB IH].
129+
+ now exists nil.
130+
+ destruct (Su b) as (a,E).
131+
destruct IH as (lA,IC).
132+
exists (a::lA). simpl. rewrite E.
133+
intros x [X|X]; simpl; intuition.
134+
- intros H y.
135+
destruct (H (y::nil)) as (lA,IC).
136+
assert (IN : In y (map f lA)) by (apply (IC y); now left).
137+
rewrite in_map_iff in IN. destruct IN as (x & E & _).
138+
now exists x.
139+
Qed.
140+
141+
Lemma Surjective_carac A B : Finite B -> decidable_eq B ->
142+
forall f:A->B, Surjective f <-> (exists lA, Listing (map f lA)).
143+
Proof.
144+
intros (lB,FB) d f. split.
145+
- rewrite Surjective_list_carac.
146+
intros Su. destruct (Su lB) as (lA,IC).
147+
destruct (uniquify_map d f lA) as (lA' & N & IC').
148+
exists lA'. split; trivial.
149+
intro x. apply IC', IC, FB.
150+
- intros (lA & N & FA) y.
151+
generalize (FA y). rewrite in_map_iff. intros (x & E & _).
152+
now exists x.
153+
Qed.
154+
155+
(** Main result : *)
156+
157+
Lemma Endo_Injective_Surjective :
158+
forall A, Finite A -> decidable_eq A ->
159+
forall f:A->A, Injective f <-> Surjective f.
160+
Proof.
161+
intros A F d f. rewrite (Surjective_carac F d). split.
162+
- assert (Finite' A) as (l, L) by (now apply Finite_dec); clear F.
163+
rewrite (Injective_carac L); intros.
164+
exists l; split; trivial.
165+
destruct L as (N,F).
166+
assert (I : incl l (map f l)).
167+
{ apply NoDup_length_incl; trivial.
168+
- now rewrite length_map.
169+
- intros x _. apply F. }
170+
intros x. apply I, F.
171+
- clear F d. intros (l,L).
172+
assert (N : NoDup l). { apply (NoDup_map_inv f), L. }
173+
assert (I : incl (map f l) l).
174+
{ apply NoDup_length_incl; trivial.
175+
- now rewrite length_map.
176+
- intros x _. apply L. }
177+
assert (L' : Listing l).
178+
{ split; trivial.
179+
intro x. apply I, L. }
180+
apply (Injective_carac L'), L.
181+
Qed.
182+
183+
(** An injective and surjective function is bijective.
184+
We need here stronger hypothesis : decidability of equality in Type. *)
185+
186+
Definition EqDec (A:Type) := forall x y:A, {x=y}+{x<>y}.
187+
188+
(** First, we show that a surjective f has an inverse function g such that
189+
f.g = id. *)
190+
191+
(* NB: instead of (Finite A), we could ask for (RecEnum A) with:
192+
Definition RecEnum A := exists h:nat->A, surjective h.
193+
*)
194+
195+
Lemma Finite_Empty_or_not A :
196+
Finite A -> (A->False) \/ exists a:A,True.
197+
Proof.
198+
intros (l,F).
199+
destruct l as [|a l].
200+
- left; exact F.
201+
- right; now exists a.
202+
Qed.
203+
204+
Lemma Surjective_inverse :
205+
forall A B, Finite A -> EqDec B ->
206+
forall f:A->B, Surjective f ->
207+
exists g:B->A, forall x, f (g x) = x.
208+
Proof.
209+
intros A B F d f Su.
210+
destruct (Finite_Empty_or_not F) as [noA | (a,_)].
211+
- (* A is empty : g is obtained via False_rect *)
212+
assert (noB : B -> False). { intros y. now destruct (Su y). }
213+
exists (fun y => False_rect _ (noB y)).
214+
intro y. destruct (noB y).
215+
- (* A is inhabited by a : we use it in Option.get *)
216+
destruct F as (l,F).
217+
set (h := fun x k => if d (f k) x then true else false).
218+
set (get := fun o => match o with Some y => y | None => a end).
219+
exists (fun x => get (List.find (h x) l)).
220+
intros x.
221+
case_eq (find (h x) l); simpl; clear get; [intros y H|intros H].
222+
* apply find_some in H. destruct H as (_,H). unfold h in H.
223+
now destruct (d (f y) x) in H.
224+
* exfalso.
225+
destruct (Su x) as (y & Y).
226+
generalize (find_none _ l H y (F y)).
227+
unfold h. now destruct (d (f y) x).
228+
Qed.
229+
230+
(** Same, with more knowledge on the inverse function: g.f = f.g = id *)
231+
232+
Lemma Injective_Surjective_Bijective :
233+
forall A B, Finite A -> EqDec B ->
234+
forall f:A->B, Injective f -> Surjective f -> Bijective f.
235+
Proof.
236+
intros A B F d f Ij Su.
237+
destruct (Surjective_inverse F d Su) as (g, E).
238+
exists g. split; trivial.
239+
intros y. apply Ij. now rewrite E.
240+
Qed.

theories/Make.lists

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ Lists/_All/ListDec.v
22
Lists/_All/List.v
33
Lists/_All/ListSet.v
44
Lists/_All/ListTactics.v
5+
Lists/_All/Finite.v
6+
Sorting/_Lists/Permutation.v
57
Numbers/_Lists/NaryFunctions.v
68
Logic/_Lists/WKL.v
79
Classes/_Lists/EquivDec.v
810

911
-Q Lists/_All Stdlib.Lists
12+
-Q Sorting/_Lists Stdlib.Sorting
1013
-Q Numbers/_Lists Stdlib.Numbers
1114
-Q Logic/_Lists Stdlib.Logic
1215
-Q Classes/_Lists Stdlib.Classes

theories/Make.sorting

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
Sorting/Heap.v
2-
Sorting/CPermutation.v
3-
Sorting/Mergesort.v
4-
Sorting/PermutSetoid.v
5-
Sorting/PermutEq.v
6-
Sorting/Sorting.v
7-
Sorting/Permutation.v
8-
Sorting/Sorted.v
9-
Sorting/SetoidList.v
10-
Sorting/SetoidPermutation.v
1+
Sorting/_All/Heap.v
2+
Sorting/_All/CPermutation.v
3+
Sorting/_All/Mergesort.v
4+
Sorting/_All/PermutSetoid.v
5+
Sorting/_All/PermutEq.v
6+
Sorting/_All/Sorting.v
7+
Sorting/_All/Sorted.v
8+
Sorting/_All/SetoidList.v
9+
Sorting/_All/SetoidPermutation.v
1110

12-
-Q Sorting Stdlib.Sorting
11+
-Q Sorting/_All Stdlib.Sorting

0 commit comments

Comments
 (0)