Library UniMath.Combinatorics.KFiniteTypes
Require Import UniMath.Foundations.Propositions.
Require Import UniMath.MoreFoundations.PartA.
Require Import UniMath.MoreFoundations.Notations.
Require Import UniMath.MoreFoundations.DecidablePropositions.
Require Import UniMath.Combinatorics.FiniteSets.
Require Import UniMath.Combinatorics.StandardFiniteSets.
Local Open Scope stn.
Section kuratowski_structure.
1. Kuratowski structure on types.
Definition kfinstruct (X : UU) : UU
:= ∑ (n : nat)
(f : ⟦ n ⟧ → X),
issurjective f.
Definition make_kfinstruct {X : UU}
(n : nat)
(f : ⟦ n ⟧ -> X)
(fsurjective : issurjective f)
: kfinstruct X
:= (n ,, f ,, fsurjective).
Definition kfinstruct_cardinality {X : UU} (f : kfinstruct X) : nat
:= pr1 f.
Definition kfinstruct_map {X : UU} (f : kfinstruct X)
: ⟦ kfinstruct_cardinality f ⟧ -> X
:= pr12 f.
Coercion kfinstruct_map : kfinstruct >-> Funclass.
Definition issurjective_kfinstruct {X : UU}
(f : kfinstruct X) : issurjective f
:= pr22 f.
Definition kfinstruct_from_surjection {X Y : UU}
(g : X → Y)
(gsurjective : issurjective g)
: kfinstruct X → kfinstruct Y.
Proof.
intros f.
use make_kfinstruct.
- exact(kfinstruct_cardinality f).
- exact(g ∘ f).
- apply issurjcomp.
apply issurjective_kfinstruct.
exact gsurjective.
Defined.
Definition kfinstruct_weqf {X Y : UU}
(w : X ≃ Y) : kfinstruct X → kfinstruct Y.
Proof.
apply(kfinstruct_from_surjection w).
apply issurjectiveweq.
apply weqproperty.
Defined.
Definition kfinstruct_weqb {X Y : UU}
(w : X ≃ Y) : kfinstruct Y → kfinstruct X.
Proof.
apply(kfinstruct_from_surjection (invmap w)).
apply issurjectiveweq.
apply isweqinvmap.
Defined.
Definition kfinstruct_contr {X : UU}
(contr : iscontr X)
: kfinstruct X.
Proof.
use(make_kfinstruct 1).
- exact(λ _, iscontrpr1 contr).
- apply issurjective_to_contr, contr.
exact(● 0).
Defined.
Definition kfinstruct_coprod {X Y : UU}
: kfinstruct X → kfinstruct Y → kfinstruct (X ⨿ Y).
Proof.
intros f g.
set (n := kfinstruct_cardinality f).
set (m := kfinstruct_cardinality g).
use make_kfinstruct.
- exact(n + m).
- exact((coprodf f g) ∘ invweq (weqfromcoprodofstn n m)).
- apply issurjcomp.
+ apply issurjectiveweq.
apply weqproperty.
+ apply issurjective_coprodf
; apply issurjective_kfinstruct.
Defined.
Definition kfinstruct_dirprod {X Y : UU}
: kfinstruct X -> kfinstruct Y -> kfinstruct (X × Y).
Proof.
intros f g.
set (k := kfinstruct_cardinality f).
set (l := kfinstruct_cardinality g).
use make_kfinstruct.
- exact(k * l).
- exact((dirprodf f g) ∘ (invweq (weqfromprodofstn k l))).
- apply issurjcomp.
+ apply issurjectiveweq, weqproperty.
+ apply issurjective_dirprodf
; apply issurjective_kfinstruct.
Defined.
Definition kfinstruct_finstruct {X : UU} : finstruct X → kfinstruct X.
Proof.
intros finstr.
use make_kfinstruct.
- apply finstr. - apply finstr. - apply issurjectiveweq.
apply weqproperty.
Defined.
End kuratowski_structure.
Section kstructure_examples.
:= ∑ (n : nat)
(f : ⟦ n ⟧ → X),
issurjective f.
Definition make_kfinstruct {X : UU}
(n : nat)
(f : ⟦ n ⟧ -> X)
(fsurjective : issurjective f)
: kfinstruct X
:= (n ,, f ,, fsurjective).
Definition kfinstruct_cardinality {X : UU} (f : kfinstruct X) : nat
:= pr1 f.
Definition kfinstruct_map {X : UU} (f : kfinstruct X)
: ⟦ kfinstruct_cardinality f ⟧ -> X
:= pr12 f.
Coercion kfinstruct_map : kfinstruct >-> Funclass.
Definition issurjective_kfinstruct {X : UU}
(f : kfinstruct X) : issurjective f
:= pr22 f.
Definition kfinstruct_from_surjection {X Y : UU}
(g : X → Y)
(gsurjective : issurjective g)
: kfinstruct X → kfinstruct Y.
Proof.
intros f.
use make_kfinstruct.
- exact(kfinstruct_cardinality f).
- exact(g ∘ f).
- apply issurjcomp.
apply issurjective_kfinstruct.
exact gsurjective.
Defined.
Definition kfinstruct_weqf {X Y : UU}
(w : X ≃ Y) : kfinstruct X → kfinstruct Y.
Proof.
apply(kfinstruct_from_surjection w).
apply issurjectiveweq.
apply weqproperty.
Defined.
Definition kfinstruct_weqb {X Y : UU}
(w : X ≃ Y) : kfinstruct Y → kfinstruct X.
Proof.
apply(kfinstruct_from_surjection (invmap w)).
apply issurjectiveweq.
apply isweqinvmap.
Defined.
Definition kfinstruct_contr {X : UU}
(contr : iscontr X)
: kfinstruct X.
Proof.
use(make_kfinstruct 1).
- exact(λ _, iscontrpr1 contr).
- apply issurjective_to_contr, contr.
exact(● 0).
Defined.
Definition kfinstruct_coprod {X Y : UU}
: kfinstruct X → kfinstruct Y → kfinstruct (X ⨿ Y).
Proof.
intros f g.
set (n := kfinstruct_cardinality f).
set (m := kfinstruct_cardinality g).
use make_kfinstruct.
- exact(n + m).
- exact((coprodf f g) ∘ invweq (weqfromcoprodofstn n m)).
- apply issurjcomp.
+ apply issurjectiveweq.
apply weqproperty.
+ apply issurjective_coprodf
; apply issurjective_kfinstruct.
Defined.
Definition kfinstruct_dirprod {X Y : UU}
: kfinstruct X -> kfinstruct Y -> kfinstruct (X × Y).
Proof.
intros f g.
set (k := kfinstruct_cardinality f).
set (l := kfinstruct_cardinality g).
use make_kfinstruct.
- exact(k * l).
- exact((dirprodf f g) ∘ (invweq (weqfromprodofstn k l))).
- apply issurjcomp.
+ apply issurjectiveweq, weqproperty.
+ apply issurjective_dirprodf
; apply issurjective_kfinstruct.
Defined.
Definition kfinstruct_finstruct {X : UU} : finstruct X → kfinstruct X.
Proof.
intros finstr.
use make_kfinstruct.
- apply finstr. - apply finstr. - apply issurjectiveweq.
apply weqproperty.
Defined.
End kuratowski_structure.
Section kstructure_examples.
2. Examples of types with K-structure.
Definition kfinstruct_unit : kfinstruct unit.
Proof.
apply kfinstruct_contr.
apply iscontrunit.
Defined.
Definition kfinstruct_bool : kfinstruct bool.
Proof.
use(make_kfinstruct 2).
- exact(two_rec false true).
- red; apply bool_rect; apply hinhpr.
+ exists (● 1); exact(idpath _).
+ exists (● 0); exact(idpath _).
Defined.
Definition kfinstruct_stn (n : nat) : kfinstruct (⟦ n ⟧).
Proof.
use make_kfinstruct.
- exact n.
- exact(idfun (⟦ n ⟧)).
- exact(issurjective_idfun (⟦ n ⟧)).
Defined.
Definition kfinstruct_stn_indexed {n : nat}
(P : ⟦ n ⟧ → UU)
(index : ∏ (k : ⟦ n ⟧), kfinstruct (P k))
: kfinstruct (∑ (k : ⟦ n ⟧), P k).
Proof.
set (J := λ (j : ⟦ n ⟧), kfinstruct_cardinality (index j)).
use(kfinstruct_from_surjection (X:=∑ (k : ⟦n⟧), ⟦J k⟧)).
- apply totalfun, index.
- apply issurjective_totalfun.
intro; apply issurjective_kfinstruct.
- apply(kfinstruct_weqb (weqstnsum1 J)).
apply kfinstruct_stn.
Defined.
End kstructure_examples.
Section kfinite_definition.
3. The property of being K-finite.
A type is Kuratowski finite if it merely admits a K-structure.
Definition iskfinite (X : UU) : UU
:= ∥ kfinstruct X ∥.
Definition kfinstruct_iskfinite {X : UU} : kfinstruct X → iskfinite X
:= hinhpr.
Definition iskfinite_weqf {X Y : UU} (w : X ≃ Y)
: iskfinite X → iskfinite Y
:= hinhfun (kfinstruct_weqf w).
Definition iskfinite_weqb {X Y : UU} (w : X ≃ Y)
: iskfinite Y → iskfinite X
:= hinhfun (kfinstruct_weqb w).
Definition iskfinite_from_surjection {X Y : UU}
(f : X → Y)
(fsurjective : issurjective f)
: iskfinite X → iskfinite Y
:= hinhfun (kfinstruct_from_surjection f fsurjective).
Definition iskfinite_unit : iskfinite unit
:= hinhpr kfinstruct_unit.
Definition iskfinite_bool : iskfinite bool
:= hinhpr kfinstruct_bool.
Definition iskfinite_contr (X : UU) (Xcontr : iscontr X) : iskfinite X
:= hinhpr (kfinstruct_contr Xcontr).
Definition iskfinite_coprod {X Y : UU}
: iskfinite X → iskfinite Y → iskfinite (X ⨿ Y)
:= hinhfun2
kfinstruct_coprod.
Definition iskfinite_dirprod {X Y : UU}
: iskfinite X → iskfinite Y → iskfinite (X × Y)
:= hinhfun2
kfinstruct_dirprod.
Definition iskfinite_isfinite {X : UU}
: isfinite X → iskfinite X
:= hinhfun kfinstruct_finstruct.
End kfinite_definition.
Section iskfinite_isdeceq_isfinite.
Lemma issurjective_stnfun_singleton_complement {X : UU} {n : nat} (f : stn (S n) → X)
(nfib : ¬ hfiber (fun_stnsn_to_stnn f) (f lastelement)) : issurjective f →
issurjective (stnfun_singleton_complement f nfib).
Proof.
intros surjf y.
destruct y as [x neq].
use squash_to_prop.
- exact (hfiber f x).
- exact (surjf x).
- apply propproperty.
- intros [[m lth] q]; clear surjf. apply hinhpr.
induction (natlehchoice _ _ (natlthsntoleh _ _ lth)).
+ apply (tpair _ (m ,, a)).
unfold stnfun_singleton_complement, fun_stnsn_to_stnn, make_stn.
apply subtypePath_prop; cbn.
induction q. apply maponpaths, stn_eq, idpath.
+ assert (H : (m ,, lth = lastelement)) by apply stn_eq, b.
apply fromempty. induction neq. induction H. apply pathsinv0, q.
Qed.
Lemma kfinstruct_dec_finstruct {X : UU} : isdeceq X → kfinstruct X → finstruct X.
Proof.
intros deceqX [n [f surj]].
generalize dependent X.
induction n; intros.
- apply tpair with (pr1 := 0).
apply surj_from_stn0_to_neg with (f := f). assumption.
- set (g := fun_stnsn_to_stnn f).
set (y := f lastelement).
induction (isdeceq_isdecsurj g y deceqX).
+ apply IHn with (f := g); try apply surj_fun_stnsn_to_stnn; assumption.
+ set (g' := stnfun_singleton_complement f b).
set (surjg' := (issurjective_stnfun_singleton_complement f b surj)).
specialize IHn with (f := g').
apply IHn in surjg';
[ | apply isdeceq_subtype; try assumption; intros x; apply isapropneg ].
destruct surjg' as [s1 s2].
apply tpair with (pr1 := (S s1)); unfold nelstruct.
eapply weqcomp.
* apply invweq, weqdnicoprod, lastelement.
* eapply weqcomp.
{ eapply weqcoprodf1, s2. }
apply weq_singleton_complement_unit; assumption.
Qed.
Lemma iskfinite_dec_to_isfinite {X : UU} : isdeceq X → iskfinite X → isfinite X.
Proof.
intros deceqX. apply hinhfun, kfinstruct_dec_finstruct, deceqX.
Qed.
End iskfinite_isdeceq_isfinite.