# Library LinAlg.support.finite_subsets

Set Implicit Arguments.
Unset Strict Implicit.
Require Export Diff.
Require Export Singleton.
Require Export cast_between_subsets.
Require Export empty.
Require Export Classical_Prop.

• A set is finite if we can list its elements (possibly with duplicates in the list)

Definition is_finite_set (A : Setoid) :=
n : Nat, ( v : seq n A, full A =' seq_set v in _).

• For subsets, the following notion is more useful as it removes one one layer of taking subsets:
Definition is_finite_subset (A : Setoid) (B : part_set A) :=
n : Nat, ( v : seq n A, B =' seq_set v in _).

Lemma is_finite_subset_comp :
(A : Setoid) (B C : part_set A),
B =' C in _is_finite_subset Bis_finite_subset C.
red in |- ×.
intros.
red in H0.
inversion H0.
inversion H1.
x.
x0.
apply Trans with B; auto with algebra.
Qed.

• There is no corresponding is_finite_set_comp, for there is no 'master' setoid wherein two Setoids can be compared.

Hint Resolve is_finite_subset_comp: algebra.

Lemma is_finite_subset_then_is_finite :
(A : Setoid) (B : part_set A), is_finite_subset Bis_finite_set B.
intros.
red in |- *; red in H.
inversion_clear H; inversion_clear H0.
x.
assert ( i : fin x, in_part (x0 i) B).
simpl in H; red in H; simpl in H.
intros.
elim (H (x0 i)).
intros p q; (apply q; auto with algebra).
i; auto with algebra.
(cast_map_to_subset H0).
simpl in |- *; red in |- *; simpl in |- *; split; intro; auto.
unfold subtype_image_equal in |- ×.
simpl in H; red in H; simpl in H.
elim (H (subtype_elt x1)).
intros.
assert (in_part (subtype_elt x1) B).
auto with algebra.
elim (H2 H4).
intros.
x2.
apply Trans with (x0 x2); auto with algebra.
Qed.

Lemma is_finite_set_then_is_finite_subset :
(A : Setoid) (B : part_set A), is_finite_set Bis_finite_subset B.
intros; red in |- *; red in H.
inversion_clear H; inversion_clear H0.
x; (Map_embed x0).
destruct x0; simpl in H; red in H; simpl in H; simpl in |- *; red in |- *;
simpl in |- ×.
split; intros.
red in H0; elim (H (Build_subtype H0)).
intros p _; generalize (p I); clear p; intro.
inversion_clear H1.
red in H2.
x1.
simpl in H2.
auto.
inversion_clear H0.
apply in_part_comp_l with (subtype_elt (Ap x1)); auto with algebra.
Qed.

Lemma seq_set_is_finite_subset :
(A : Setoid) (n : Nat) (v : seq n A), is_finite_subset (seq_set v).
intros.
red in |- ×.
n.
v.
auto with algebra.
Qed.

• This one is surprisingly hard to prove (or did I not think hard enough?)

Lemma included_reflects_is_finite_subset :
(A : Setoid) (B C : part_set A),
is_finite_subset Cincluded B Cis_finite_subset B.
intros.
red in H.
inversion_clear H.
generalize B C H0 H1.
clear H1 H0 C B.
induction x as [| x Hrecx].
intros.
inversion_clear H1.
assert (C =' empty A in _).
apply Trans with (seq_set x); auto with algebra.
clear H x.
assert (included B (empty A)).
apply included_comp with B C; auto with algebra.
red in H.
red in |- ×.
0; (empty_seq A).
apply Trans with (empty A); auto with algebra.
split.
intro; auto.
intro p; simpl in p; contradiction.

intros.
inversion_clear H1.
assert (in_part (head x0) B ¬ in_part (head x0) B); try apply classic.
inversion_clear H1.
assert (included (diff B (single (head x0))) (seq_set (Seqtl x0))).
red in |- ×.
intros.
simpl in H1.
inversion_clear H1.
red in H0.
generalize (H0 x1 H3).
intro.
assert (in_part x1 (seq_set x0)).
apply in_part_comp_r with C; auto with algebra.
simpl in H5.
inversion_clear H5.
assert (¬ x2 =' Build_finiteT (lt_O_Sn x) in fin (S x)).
red in |- *; red in H4; intro; apply H4.
apply Trans with (x0 x2); auto with algebra.
assert
( i : fin x,
x2 ='
match i with
| Build_finiteT n HnBuild_finiteT (lt_n_S _ _ Hn)
end in fin (S x)).
clear H6 H1 H4 H3 x1 H2 H x0 H0 C B Hrecx A.
destruct x2.
simpl in H5.
simpl in |- ×.
assert ( n : Nat, index = S n).
destruct index as [| n].
absurd (0 = 0); auto.
n.
auto.
inversion_clear H.
rewrite H0 in in_range_prf.
(Build_finiteT (lt_S_n _ _ in_range_prf)).
simpl in |- ×.
auto.
inversion_clear H7.
destruct x3.
apply in_part_comp_l with (x0 (Build_finiteT (lt_n_S _ _ in_range_prf)));
auto with algebra.
simpl in |- ×.
(Build_finiteT in_range_prf).
auto with algebra.
apply Trans with (x0 x2); auto with algebra.

generalize (Hrecx _ _ H1).
intros.
assert ( v : seq x A, seq_set (Seqtl x0) =' seq_set v in _).
(Seqtl x0).
auto with algebra.
generalize (H3 H4); clear H4 H3; intros.
red in H3.
inversion_clear H3.
inversion_clear H4.
red in |- ×.
(S x1).
assert
( x : A,
in_part x Bx =' head x0 in _ in_part x (diff B (single (head x0)))).
simpl in |- ×.
intros.
case (classic (x3 =' head x0 in _)); intro.
left; auto.
right; auto.
simpl in |- ×.
red in |- ×.
intros.
split.
intro.
generalize (H4 x3 H5); clear H4; intros.
simpl in |- ×.
case H4; clear H4; intros.
(Build_finiteT (lt_O_Sn x1)).
auto.
simpl in H3; red in H3.
generalize (H3 x3); clear H3; intros.
inversion_clear H3.
generalize (H6 H4); clear H6; intros.
simpl in H3.
inversion_clear H3.
destruct x4.
(Build_finiteT (lt_n_S _ _ in_range_prf)).
apply Trans with (x2 (Build_finiteT in_range_prf)); auto with algebra.
intros.
simpl in H5.
inversion_clear H5.
destruct x4.
destruct index as [| n].
apply in_part_comp_l with (head x0); auto with algebra.
assert (included (diff B (single (head x0))) B).
red in |- ×.
intros.
simpl in H5.
inversion_clear H5; auto.
red in H5.
apply H5; auto with algebra.
apply in_part_comp_r with (seq_set x2); auto with algebra.
simpl in |- ×.
(Build_finiteT (lt_S_n n x1 in_range_prf)).
auto.

assert (included B (seq_set (Seqtl x0))).
red in |- ×.
intros.
red in H0.
generalize (H0 _ H1).
intro.
assert (in_part x1 (seq_set x0)).
apply in_part_comp_r with C; auto with algebra.
clear H3; simpl in H4.
inversion_clear H4.
assert (¬ x2 =' Build_finiteT (lt_O_Sn x) in fin (S x)).
red in |- *; red in H2; intro; apply H2.
apply in_part_comp_l with x1; auto with algebra.
apply Trans with (x0 x2); auto with algebra.
simpl in |- ×.
assert
( i : fin x,
x2 ='
match i with
| Build_finiteT n HnBuild_finiteT (lt_n_S _ _ Hn)
end in fin (S x)).
destruct x2.
destruct index as [| n].
simpl in H4.
absurd (0 = 0); auto.
clear H4.
(Build_finiteT (lt_S_n _ _ in_range_prf)).
simpl in |- ×.
auto.
inversion_clear H5.
x3.
destruct x3.
apply Trans with (x0 x2); auto with algebra.
apply (Hrecx _ _ H1); auto with algebra.
(Seqtl x0); auto with algebra.
Qed.