HITs-Examples/FiniteSets/variations/enumerated.v

289 lines
8.6 KiB
Coq
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(* Enumerated finite sets *)
Require Import HoTT HitTactics.
Require Import disjunction Sub.
Require Import representations.cons_repr representations.definition.
Require Import variations.k_finite.
From fsets Require Import operations isomorphism properties_decidable operations_decidable.
Fixpoint listExt {A} (ls : list A) : Sub A := fun x =>
match ls with
| nil => False_hp
| cons a ls' => BuildhProp (Trunc (-1) (x = a)) listExt ls' x
end.
Fixpoint map {A B} (f : A -> B) (ls : list A) : list B :=
match ls with
| nil => nil
| cons x xs => cons (f x) (map f xs)
end.
Fixpoint filterD {A} (P : A -> Bool) (ls : list A) : list { x : A | P x = true }.
Proof.
destruct ls as [|x xs].
- exact nil.
- enough ((P x = true) + (P x = false)) as HP.
{ destruct HP as [HP | HP].
+ refine (cons (exist _ x HP) (filterD _ P xs)).
+ refine (filterD _ P xs).
}
{ destruct (P x); [left | right]; reflexivity. }
Defined.
Lemma filterD_cons {A} (P : A -> Bool) (a : A) (ls : list A) (Pa : P a = true) :
filterD P (cons a ls) = cons (a;Pa) (filterD P ls).
Proof.
simpl.
destruct (if P a as b return ((b = true) + (b = false))
then inl 1%path
else inr 1%path) as [Pa' | Pa'].
- rewrite (set_path2 Pa Pa'). reflexivity.
- rewrite Pa in Pa'. contradiction (true_ne_false Pa').
Defined.
Lemma filterD_cons_no {A} (P : A -> Bool) (a : A) (ls : list A) (Pa : P a = false) :
filterD P (cons a ls) = filterD P ls.
Proof.
simpl.
destruct (if P a as b return ((b = true) + (b = false))
then inl 1%path
else inr 1%path) as [Pa' | Pa'].
- rewrite Pa' in Pa. contradiction (true_ne_false Pa).
- reflexivity.
Defined.
Lemma filterD_lookup {A} (P : A -> Bool) (x : A) (ls : list A) (Px : P x = true) :
listExt ls x -> listExt (filterD P ls) (x;Px).
Proof.
induction ls as [| a ls].
- simpl. exact idmap.
- assert ((P a = true) + (P a = false)) as HPA.
{ destruct (P a); [left | right]; reflexivity. }
destruct HPA as [Pa | Pa].
+ rewrite (filterD_cons P a ls Pa). simpl.
simple refine (Trunc_ind _ _). intros [Hxa | HIH]; apply tr.
* left. strip_truncations.
apply tr.
apply path_sigma' with Hxa.
apply set_path2.
* right. apply (IHls HIH).
+ rewrite (filterD_cons_no P a ls Pa). simpl.
simple refine (Trunc_ind _ _). intros [Hxa | HIH].
* strip_truncations.
rewrite <- Hxa in Pa. rewrite Px in Pa.
contradiction (true_ne_false Pa).
* apply IHls. apply HIH.
Defined.
(** Definition of finite sets in an enumerated sense *)
Definition enumerated (A : Type) : hProp :=
hexists (fun ls => forall (a : A), listExt ls a).
(** Properties of enumerated sets: closed under decidable subsets *)
Lemma enumerated_comprehension (A : Type) (P : A -> Bool) :
enumerated A -> enumerated { x : A | P x = true }.
Proof.
intros HeA. strip_truncations. destruct HeA as [eA HeA].
apply tr.
exists (filterD P eA).
intros [x Px].
apply filterD_lookup.
apply (HeA x).
Defined.
Lemma map_listExt {A B} (f : A -> B) (ls : list A) (y : A) :
listExt ls y -> listExt (map f ls) (f y).
Proof.
induction ls.
- simpl. apply idmap.
- simpl. simple refine (Trunc_ind _ _). intros [Hxa | HIH]; apply tr.
+ left. strip_truncations. apply tr. f_ap.
+ right. apply IHls. apply HIH.
Defined.
(** Properties of enumerated sets: closed under surjections *)
Lemma enumerated_surj (A B : Type) (f : A -> B) :
IsSurjection f -> enumerated A -> enumerated B.
Proof.
intros Hsurj HeA. strip_truncations; apply tr.
destruct HeA as [eA HeA].
exists (map f eA).
intros x. specialize (Hsurj x).
pose (t := center (merely (hfiber f x))).
simple refine (@Trunc_rec (-1) (hfiber f x) (listExt (map f eA) x) _ _ t).
intros [y Hfy].
specialize (HeA y). rewrite <- Hfy.
apply map_listExt. apply HeA.
Defined.
Lemma listExt_app_r {A} (ls ls' : list A) (x : A) :
listExt ls x -> listExt (ls ++ ls') x.
Proof.
induction ls; simpl.
- exact Empty_rec.
- simple refine (Trunc_ind _ _). intros [Hxa | HIH]; apply tr.
+ left. apply Hxa.
+ right. apply IHls. apply HIH.
Defined.
Lemma listExt_app_l {A} (ls ls' : list A) (x : A) :
listExt ls x -> listExt (ls' ++ ls) x.
Proof.
induction ls'; simpl.
- apply idmap.
- intros Hls.
apply tr.
right. apply IHls'. apply Hls.
Defined.
(** Properties of enumerated sets: closed under sums *)
Lemma enumerated_sum (A B : Type) :
enumerated A -> enumerated B -> enumerated (A + B).
Proof.
intros HeA HeB.
strip_truncations; apply tr.
destruct HeA as [eA HeA], HeB as [eB HeB].
exists (app (map inl eA) (map inr eB)).
intros [x | x].
- apply listExt_app_r. apply map_listExt. apply HeA.
- apply listExt_app_l. apply map_listExt. apply HeB.
Defined.
Fixpoint listProd_sing {A B} (x : A) (ys : list B) : list (A * B).
Proof.
destruct ys as [|y ys].
- exact nil.
- refine (cons (x,y) _).
apply (listProd_sing _ _ x ys).
Defined.
Fixpoint listProd {A B} (xs : list A) (ys : list B) : list (A * B).
Proof.
destruct xs as [|x xs].
- exact nil.
- refine (app _ _).
+ exact (listProd_sing x ys).
+ exact (listProd _ _ xs ys).
Defined.
Lemma listExt_prod_sing {A B} (x : A) (y : B) (ys : list B) :
listExt ys y -> listExt (listProd_sing x ys) (x, y).
Proof.
induction ys; simpl.
- exact idmap.
- simple refine (Trunc_ind _ _). intros [Hxy | HIH]; simpl; apply tr.
+ left. strip_truncations. apply tr. f_ap.
+ right. apply IHys. apply HIH.
Defined.
Lemma listExt_prod `{Funext} {A B} (xs : list A) (ys : list B) : forall (x : A) (y : B),
listExt xs x -> listExt ys y -> listExt (listProd xs ys) (x,y).
Proof.
induction xs as [| x' xs]; intros x y.
- simpl. contradiction.
- simpl. simple refine (Trunc_ind _ _). intros Htx. simpl.
induction ys as [| y' ys].
+ simpl. contradiction.
+ simpl. simple refine (Trunc_ind _ _). intros Hty. simpl. apply tr.
destruct Htx as [Hxx' | Hxs], Hty as [Hyy' | Hys].
* left. strip_truncations. apply tr. f_ap.
* right. strip_truncations. rewrite <- Hxx'. clear Hxx'.
apply listExt_app_r.
apply listExt_prod_sing. assumption.
* right. strip_truncations. rewrite <- Hyy'.
rewrite <- Hyy' in IHxs.
apply listExt_app_l. apply IHxs. assumption.
simpl. apply tr. left. apply tr. reflexivity.
* right.
apply listExt_app_l.
apply IHxs. assumption.
simpl. apply tr. right. assumption.
Defined.
(** Properties of enumerated sets: closed under products *)
Lemma enumerated_prod (A B : Type) `{Funext} :
enumerated A -> enumerated B -> enumerated (A * B).
Proof.
intros HeA HeB.
strip_truncations; apply tr.
destruct HeA as [eA HeA], HeB as [eB HeB].
exists (listProd eA eB).
intros [x y].
apply listExt_prod; [ apply HeA | apply HeB ].
Defined.
(** If a set is enumerated is it Kuratowski-finite *)
Section enumerated_fset.
Variable A : Type.
Context `{Univalence}.
Fixpoint list_to_fset (ls : list A) : FSet A :=
match ls with
| nil =>
| cons x xs => {|x|} (list_to_fset xs)
end.
Lemma list_to_fset_ext (ls : list A) (a : A):
listExt ls a -> isIn a (list_to_fset ls).
Proof.
induction ls as [|x xs]; simpl.
- apply idmap.
- intros Hin.
strip_truncations. apply tr.
destruct Hin as [Hax | Hin].
+ left. exact Hax.
+ right. by apply IHxs.
Defined.
Lemma enumerated_Kf : enumerated A -> Kf A.
Proof.
intros Hls.
strip_truncations.
destruct Hls as [ls Hls].
exists (list_to_fset ls).
apply path_forall. intro a.
symmetry. apply path_hprop.
apply if_hprop_then_equiv_Unit. apply _.
by apply list_to_fset_ext.
Defined.
End enumerated_fset.
Section fset_dec_enumerated.
Variable A : Type.
Context `{Univalence}.
Definition Kf_fsetc :
Kf A -> exists (X : FSetC A), forall (a : A), k_finite.map (FSetC_to_FSet X) a.
Proof.
intros [X HX].
exists (FSet_to_FSetC X).
rewrite repr_iso_id_l.
by rewrite <- HX.
Defined.
Definition merely_enumeration_FSetC :
forall (X : FSetC A),
hexists (fun (ls : list A) => forall a, a (FSetC_to_FSet X) = listExt ls a).
Proof.
hinduction.
- apply tr. exists nil. simpl. done.
- intros a X Hls.
strip_truncations. apply tr.
destruct Hls as [ls Hls].
exists (cons a ls). intros b. simpl.
f_ap.
- intros. apply path_ishprop.
- intros. apply path_ishprop.
Defined.
Definition Kf_enumerated : Kf A -> enumerated A.
Proof.
intros HKf. apply Kf_fsetc in HKf.
destruct HKf as [X HX].
pose (ls' := (merely_enumeration_FSetC X)).
simple refine (@Trunc_rec _ _ _ _ _ ls'). clear ls'.
intros [ls Hls].
apply tr. exists ls.
intros a. rewrite <- Hls. apply (HX a).
Defined.
End fset_dec_enumerated.