Setssets, cardinality, and countability
Syntax for sets
    bool = { true, false }
 
    sdos = { 1, 3, 5, 7, 9 }
 
A word about priorities
Ordinarily, we've defined all of our types inductively. The
    keyword Parameter here means we're not specifying how sets are
    actually defined—there are no constructors. 
In lieu of constructors, we'll assume that there are three relevant sets: 
 
 
- The empty set, typically written ∅.
- The universal set, which holds every object of type X. Typically called U or Univ.
-  The set specified by a predicate: given P : X → Prop, the set
    of objects a : X such that P a.
Such sets are typically constructed with set-builder notation, where {x | P} denotes the set of x such that P.Paper use of set-builder notation will sometimes indicate x's type or the set its being drawn from, e.g., {x : nat | ∃k, x = 2*k} specifies the even naturals. On paper, multiple premises will sometimes be separated by a comma, as in {x : nat | ∃ k, x = 2 * k, x > 2} denotes the evens counting from 4. A more precise notation would write {x : nat | (∃k, x = 2 * k) ∧ x > 2}.
Given our three set formers, there is one key predicate on sets:
    membership. A set contains its members, as {true,false} was
    seen to contain true above.
 
    We typically write a ∈ X to mean that a is in X. Other
    phrasing include "is an element of", "belongs to", "is a member
    of", "is included in". One might also say X contains a or has
    a as a member. 
If two sets contain the same elements, they are the same
    set. (Compare to functional extensionality in Logic.v. 
In our formulation of sets, there can be no ambiguity: each
    element is either in or not in the set.
 
    That is, we'll just assume that the law of the excluded middle
    applies to sets.  
Nothing is a member of the empty set—it's empty! 
But everything is a member of the universal set, since it contains
    everything. 
Finally, an element is a member of a set built with set-builder
    notation when it satisfies the predicate. Stating this as separate
    axioms helps Coq do a better job with inference—if we state the
    iff explicitly, Coq sometimes guesses wrong when we apply the
    axiom. 
 
Axiom member_spec_P : ∀ X (P : X → Prop),
∀ x, Member x (Spec P) → P x.
Axiom P_member_spec : ∀ X (P : X → Prop),
∀ x, P x → Member x (Spec P).
∀ x, Member x (Spec P) → P x.
Axiom P_member_spec : ∀ X (P : X → Prop),
∀ x, P x → Member x (Spec P).
Given these primitives, we can derive common notions of
    sets. We'll use Spec extensively.
 
    First, the singleton set holds just one element; it's written {x}. 
The union of two sets holds all of those elements in either of
    those sets; it's written S1 ∪ S2. 
The intersection of two sets holds the elements common to both
    sets; it's written S1 ∩ S2. 
Definition Intersection {X:Type} (S1 S2 : set X) : set X :=
Spec (fun x ⇒ Member x S1 ∧ Member x S2).
Spec (fun x ⇒ Member x S1 ∧ Member x S2).
Note the deliberate similarity between union/intersection (∪/∩)
    and disjunction/conjunction (∨/∧). 
 
 The difference between two sets are those elements in the first
    set but not the second. There are two notations in common use: S1
    \ S2 and S1 - S2. 
Definition Difference {X:Type} (S1 S2 : set X) : set X :=
Spec (fun x ⇒ Member x S1 ∧ ~(Member x S2)).
Spec (fun x ⇒ Member x S1 ∧ ~(Member x S2)).
The complement of a set are those elements not in the set. To
    have a complement, we need a notion of a "universe" which elements
    are we to consider when picking those elements not in the set?
 
    Coq's types give us a natural notion: if S : set X, then
    Complement S consists of those values of type X that weren't
    in S. So, for example, Complement {true,false} = ∅ and the
    complement of the odd naturals are the even naturals.
 
    The common notation for complement is to draw a line over the set
    in question. One can also write U - S, where U stands for the
    universal set. (See complement__universe_difference for a
    justification.)  
Given these definitions, we can use the axioms to characterize set
    membership for our various operations. 
 
Exercise: 2 stars, optional (set_properties)
These are some nice properties of sets; proving them shouldn't be too difficult and is nice practice both in Coq and, more importantly, working with sets.
Lemma member_singleton : ∀ X (x y:X),
Member x (Singleton y) ↔ x = y.
Proof.
(* FILL IN HERE *) Admitted.
Lemma member_union : ∀ X (S1 S2 : set X) (x : X),
Member x (Union S1 S2) ↔ Member x S1 ∨ Member x S2.
Proof.
(* FILL IN HERE *) Admitted.
Lemma member_intersection : ∀ X (S1 S2 : set X) (x : X),
Member x (Intersection S1 S2) ↔ Member x S1 ∧ Member x S2.
Proof.
(* FILL IN HERE *) Admitted.
Lemma member_difference : ∀ X (S1 S2 : set X) (x : X),
Member x (Difference S1 S2) ↔ Member x S1 ∧ ~(Member x S2).
Proof.
(* FILL IN HERE *) Admitted.
Lemma member_complement : ∀ X (S : set X) (x : X),
Member x (Complement S) ↔ ~(Member x S).
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Member x (Singleton y) ↔ x = y.
Proof.
(* FILL IN HERE *) Admitted.
Lemma member_union : ∀ X (S1 S2 : set X) (x : X),
Member x (Union S1 S2) ↔ Member x S1 ∨ Member x S2.
Proof.
(* FILL IN HERE *) Admitted.
Lemma member_intersection : ∀ X (S1 S2 : set X) (x : X),
Member x (Intersection S1 S2) ↔ Member x S1 ∧ Member x S2.
Proof.
(* FILL IN HERE *) Admitted.
Lemma member_difference : ∀ X (S1 S2 : set X) (x : X),
Member x (Difference S1 S2) ↔ Member x S1 ∧ ~(Member x S2).
Proof.
(* FILL IN HERE *) Admitted.
Lemma member_complement : ∀ X (S : set X) (x : X),
Member x (Complement S) ↔ ~(Member x S).
Proof.
(* FILL IN HERE *) Admitted.
Lemma complement__universe_difference : ∀ X (S : set X),
Complement S = Difference Universe S.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Complement S = Difference Universe S.
Proof.
(* FILL IN HERE *) Admitted.
If A is included in B but doesn't comprise all of B, then
    A is a proper subset of B; we write A ⊂ B or A ⊊ B.
 
    Be careful, though: some authors will write A ⊂ B to mean
    plain (not necessarily proper) subset. 
The subset relation is reflexive and transitive. 
Lemma subset_refl : ∀ X (S : set X),
subset S S.
Proof.
intros X S. unfold subset. intros x H. apply H.
Qed.
Lemma subset_trans : ∀ X (S1 S2 S3 : set X),
subset S1 S2 → subset S2 S3 → subset S1 S3.
Proof.
intros X S1 S2 S3 H12 H23.
intros x H.
apply H23.
apply H12.
apply H.
Qed.
subset S S.
Proof.
intros X S. unfold subset. intros x H. apply H.
Qed.
Lemma subset_trans : ∀ X (S1 S2 S3 : set X),
subset S1 S2 → subset S2 S3 → subset S1 S3.
Proof.
intros X S1 S2 S3 H12 H23.
intros x H.
apply H23.
apply H12.
apply H.
Qed.
Subset also provides a way to prove equality of sets: if two sets
    are subsets of each other, they must be equal. Such a proof of
    equality is "a proof by mutual inclusion". 
Lemma subset_eq : ∀ X (S1 S2 : set X),
subset S1 S2 ∧ subset S2 S1 ↔ S1 = S2.
Proof.
intros X S1 S2.
split.
- unfold subset. intros [H12 H21].
apply extensionality. intros x.
split.
+ apply H12.
+ apply H21.
- intros Heq. rewrite Heq. split.
+ apply subset_refl.
+ apply subset_refl.
Qed.
subset S1 S2 ∧ subset S2 S1 ↔ S1 = S2.
Proof.
intros X S1 S2.
split.
- unfold subset. intros [H12 H21].
apply extensionality. intros x.
split.
+ apply H12.
+ apply H21.
- intros Heq. rewrite Heq. split.
+ apply subset_refl.
+ apply subset_refl.
Qed.
Lemma empty_subset : ∀ X (S : set X),
subset Empty S.
Proof.
(* FILL IN HERE *) Admitted.
Lemma subset_universe : ∀ X (S : set X),
subset S Universe.
Proof.
(* FILL IN HERE *) Admitted.
Lemma union_subset : ∀ X (S1 S2 : set X),
subset (Union S1 S2) (Union S2 S1).
Proof.
(* FILL IN HERE *) Admitted.
Lemma union_comm : ∀ X (S1 S2 : set X),
Union S1 S2 = Union S2 S1.
Proof.
(* FILL IN HERE *) Admitted.
Lemma union_subset_l : ∀ X (S1 S2 : set X),
subset S1 (Union S1 S2).
Proof.
(* FILL IN HERE *) Admitted.
Corollary union_subset_r : ∀ X (S1 S2 : set X),
subset S2 (Union S1 S2).
Proof.
(* FILL IN HERE *) Admitted.
☐ 
subset Empty S.
Proof.
(* FILL IN HERE *) Admitted.
Lemma subset_universe : ∀ X (S : set X),
subset S Universe.
Proof.
(* FILL IN HERE *) Admitted.
Lemma union_subset : ∀ X (S1 S2 : set X),
subset (Union S1 S2) (Union S2 S1).
Proof.
(* FILL IN HERE *) Admitted.
Lemma union_comm : ∀ X (S1 S2 : set X),
Union S1 S2 = Union S2 S1.
Proof.
(* FILL IN HERE *) Admitted.
Lemma union_subset_l : ∀ X (S1 S2 : set X),
subset S1 (Union S1 S2).
Proof.
(* FILL IN HERE *) Admitted.
Corollary union_subset_r : ∀ X (S1 S2 : set X),
subset S2 (Union S1 S2).
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 2 stars, optional (complement_involutive)
You'll need to use inclusion_exclusion to prove this one.
Lemma complement_involutive : ∀ X (S : set X),
Complement (Complement S) = S.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Complement (Complement S) = S.
Proof.
(* FILL IN HERE *) Admitted.
For example, the power set of the booleans is:
 
 
 
    P(bool) = { emptyset, {true}, {false}, {true, false} }
 
 
Exercise: 1 star (subset_power_set)
Lemma subset_power_set : ∀ X (S1 S2 : set X),
subset S1 S2 → subset (power_set S1) (power_set S2).
Proof.
(* FILL IN HERE *) Admitted.
☐ 
subset S1 S2 → subset (power_set S1) (power_set S2).
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 1 star (finite_sets)
Construct finite sets of words with the appropriate property. There may be more than one set with the given property; it doesn't matter which you choose. Each question builds on the previous ones.
    bamboozle ∈ X.
 
(* FILL IN HERE *)
Define a set Y such that
 
    X is a subset of Y.
 
(* FILL IN HERE *)
Define a set Z such that
 
 Z is a subset of P(X)
 
    where P(X) is the power set of X.
 
(* FILL IN HERE *)
Define a set Q such that
[ 
    the empty set is a proper subset of Q 
]
    (i.e., empty is a subset of Q but empty <> Q) and
[ 
    ∀y, if y ∈ Q then y = cheese.
]
 
(* FILL IN HERE *)
Define a set R such that
 
    ∀ x, if x ∈ R then x ∈ Q and x ≠ cheese
 
 
(* FILL IN HERE *)
☐ 
Lemma de_morgan : ∀ X (S1 S2 : set X),
Complement (Intersection (Complement S1) (Complement S2)) = Union S1 S2.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Complement (Intersection (Complement S1) (Complement S2)) = Union S1 S2.
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 2 stars (de_morgan2)
This proof can be made much easier by judicious use of of other lemmas.
Corollary de_morgan2 : ∀ X (S1 S2 : set X),
Complement (Union (Complement S1) (Complement S2)) = Intersection S1 S2.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Complement (Union (Complement S1) (Complement S2)) = Intersection S1 S2.
Proof.
(* FILL IN HERE *) Admitted.
Definition cartesian_product {X Y : Type} (Sx : set X) (Sy : set Y) : set (X * Y) :=
Spec
(fun (p:X*Y) ⇒ let (x,y) := p in Member x Sx ∧ Member y Sy).
Spec
(fun (p:X*Y) ⇒ let (x,y) := p in Member x Sx ∧ Member y Sy).
For example, the product bool × unit is { (true,tt), (false,tt) }. 
 
Exercise: 2 stars, optional (cartesian_properties)
Lemma member_cartesian : ∀ {X Y : Type} (x:X) (y:Y) (Sx : set X) (Sy : set Y),
Member (x,y) (cartesian_product Sx Sy) ↔ Member x Sx ∧ Member y Sy.
Proof.
(* FILL IN HERE *) Admitted.
Lemma empty_cartesian_identity_l : ∀ X Y (S : set Y),
cartesian_product (Empty : set X) S = Empty.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Member (x,y) (cartesian_product Sx Sy) ↔ Member x Sx ∧ Member y Sy.
Proof.
(* FILL IN HERE *) Admitted.
Lemma empty_cartesian_identity_l : ∀ X Y (S : set Y),
cartesian_product (Empty : set X) S = Empty.
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 2 stars (intersect_empty_r)
Prove that the empty set is a right identity of intersection, i.e., A ∩ ∅ = ∅.
(* FILL IN HERE *)
☐ 
Exercise: 2 stars, optional (union_idempotent)
Prove that A ∪ A = A, i.e., ∪ is idempotent.
(* FILL IN HERE *)
☐ 
Exercise: 3 stars, optional (union_assoc)
Prove that A ∪ (B ∪ C) = (A ∪ B) ∪ C, i.e., ∪ is associative. You may use any proof style you like.
(* FILL IN HERE *)
☐ 
A set-theoretic notion of relations and functions
Definition unary_relation (X : Type) : Type := set X.
Definition even_nats : unary_relation nat := Spec (fun n ⇒ ev n).
Definition even_nats' : unary_relation nat := Spec (fun n ⇒ evenb n = true).
Definition even_nats : unary_relation nat := Spec (fun n ⇒ ev n).
Definition even_nats' : unary_relation nat := Spec (fun n ⇒ evenb n = true).
For relations on two things—_binary relations, like le or =
    or Permutation—we use a set of pairs. 
For relations on more things—_ternary relations on three
    things, like R from IndProp.v—we can use larger pairs. 
So a relation R between X and Y can be intrepreted as a set
    of pairs of (a,b), where a : X and b : Y. We say a R b
    when (a,b) ∈ R. 
Definition related_in {X Y : Type} (R:binary_relation X Y) (a : X) (b : Y) : Prop :=
Member (a,b) R.
Definition empty_relation (X Y : Type) : binary_relation X Y := Empty.
Definition total_relation (X Y : Type) : binary_relation X Y := Universe.
Lemma cartesian_product__total : ∀ {X Y} (a:X) (b:Y), related_in (total_relation X Y) a b.
Proof.
intros X Y a b.
apply member_universe.
Qed.
Definition diagonal_relation (X : Type) : binary_relation X X :=
Spec (fun p : X * X ⇒ let (x,y) := p in x = y).
Definition reflexive {X : Type} (R : binary_relation X X) : Prop :=
∀ a, related_in R a a.
Definition symmetric {X : Type} (R : binary_relation X X) : Prop :=
∀ a b, related_in R a b → related_in R b a.
Definition transitive {X : Type} (R : binary_relation X X) : Prop :=
∀ a b c, related_in R a b → related_in R b c → related_in R a c.
Definition functional {X Y : Type} (R : binary_relation X Y) : Prop :=
∀ a b1 b2, related_in R a b1 → related_in R a b2 → b1 = b2.
Definition total {X Y : Type} (R : binary_relation X Y) : Prop :=
∀ a, ∃ b, related_in R a b.
Member (a,b) R.
Definition empty_relation (X Y : Type) : binary_relation X Y := Empty.
Definition total_relation (X Y : Type) : binary_relation X Y := Universe.
Lemma cartesian_product__total : ∀ {X Y} (a:X) (b:Y), related_in (total_relation X Y) a b.
Proof.
intros X Y a b.
apply member_universe.
Qed.
Definition diagonal_relation (X : Type) : binary_relation X X :=
Spec (fun p : X * X ⇒ let (x,y) := p in x = y).
Definition reflexive {X : Type} (R : binary_relation X X) : Prop :=
∀ a, related_in R a a.
Definition symmetric {X : Type} (R : binary_relation X X) : Prop :=
∀ a b, related_in R a b → related_in R b a.
Definition transitive {X : Type} (R : binary_relation X X) : Prop :=
∀ a b c, related_in R a b → related_in R b c → related_in R a c.
Definition functional {X Y : Type} (R : binary_relation X Y) : Prop :=
∀ a b1 b2, related_in R a b1 → related_in R a b2 → b1 = b2.
Definition total {X Y : Type} (R : binary_relation X Y) : Prop :=
∀ a, ∃ b, related_in R a b.
Definition R : binary_relation nat nat :=
Spec
(fun p : nat*nat ⇒
match p with
| (O,_) ⇒ False
| (S n,m) ⇒ n = m
end).
Lemma R_functional : functional R.
Proof.
(* FILL IN HERE *) Admitted.
Lemma R_not_total : ~(total R).
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Spec
(fun p : nat*nat ⇒
match p with
| (O,_) ⇒ False
| (S n,m) ⇒ n = m
end).
Lemma R_functional : functional R.
Proof.
(* FILL IN HERE *) Admitted.
Lemma R_not_total : ~(total R).
Proof.
(* FILL IN HERE *) Admitted.
Definition fR : nat → nat (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
Lemma R_fR : ∀ a b, related_in R a b → fR a = b.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Lemma R_fR : ∀ a b, related_in R a b → fR a = b.
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 1 star (R_converse)
Can you prove the converse? If so, please do so (as an informal proof). If not, prove informally that there exists an a and b such that fR a = b but ¬ (related_in R a b).
(* FILL IN HERE *)
☐ 
Exercise: 1 star (city_names)
Let C be the set of city names in the United States and let S be the set of states and provinces in the United States. Let I is a subset of C × S where c I s if the city c is in the state or province s.
(* FILL IN HERE *)
☐ 
Exercise: 1 star (broken_proof)
Find and explain the error in the following proof. Give a counterexample (i.e., give a relation R which is symmetric and transitive but not reflexive).- Theorem: If R is a subset of A × A and R is symmetric and transitive, then R is reflexive.
(* FILL IN HERE *)
☐ 
Definition domain {X Y} (f : binary_relation X Y) := X.
Definition codomain {X Y} (f : binary_relation X Y) := Y.
Definition preimage {X Y} (f : binary_relation X Y) :=
Spec (fun x ⇒ ∃ y, related_in f x y).
Definition image {X Y} (f : binary_relation X Y) :=
Spec (fun y ⇒ ∃ x, related_in f x y).
Definition codomain {X Y} (f : binary_relation X Y) := Y.
Definition preimage {X Y} (f : binary_relation X Y) :=
Spec (fun x ⇒ ∃ y, related_in f x y).
Definition image {X Y} (f : binary_relation X Y) :=
Spec (fun y ⇒ ∃ x, related_in f x y).
If a function f is total, then its preimage and domain coincide. 
Lemma total_preimage_is_whole_domain : ∀ X Y (f : binary_relation X Y),
functional f →
total f →
preimage f = Universe.
Proof.
intros X Y f Hfunc Htotal.
unfold preimage. apply extensionality.
intros x. split.
- intros H. apply member_universe.
- intros _. apply P_member_spec.
apply Htotal.
Qed.
functional f →
total f →
preimage f = Universe.
Proof.
intros X Y f Hfunc Htotal.
unfold preimage. apply extensionality.
intros x. split.
- intros H. apply member_universe.
- intros _. apply P_member_spec.
apply Htotal.
Qed.
Exercise: 3 stars (lifted_functions)
If f : A → B for some sets A and B, we can lift the function f to sets by defining f(S) = { f(s) | s ∈ S } for S is a subset of A. Prove that f(A) is the image of f.
(* FILL IN HERE *)
Prove that f(S ∪ T) = f(S) ∪ f(T) for all S, T
    is a subset of A.
 
(* FILL IN HERE *)
Prove that f(S ∩ T) is a subset of f(S) ∩ f(T). 
(* FILL IN HERE *)
Why can't you prove equality in the previous question? Give an
    example of a function f, sets A and B, and S, T is a subset of
    A where f(A) ∩ f(B) ⊊ f(A ∩ B).
 
(* FILL IN HERE *)
☐ 
Functions for counting: injections, surjections, and bijections
A function f : A → B is surjective if for every value in B,
    there's a value in A that maps to it. We also call these
    functions onto, because f maps "onto" the entirety of B.  
 
    f is surjective precisely when its codomain is equal to its image.
Definition surjective {A B : Type} (f : A → B) : Prop :=
∀ y, ∃ x, f x = y.
Definition bijective {A B : Type} (f : A → B) : Prop :=
injective f ∧ surjective f.
∀ y, ∃ x, f x = y.
Definition bijective {A B : Type} (f : A → B) : Prop :=
injective f ∧ surjective f.
Both injectivitiy and surjectivity are preserved by function
    composition. 
Lemma inj_composition : ∀ {A B C} (f : A → B) (g : B → C),
injective f →
injective g →
injective (compose f g).
Proof.
(* FILL IN HERE *) Admitted.
☐ 
injective f →
injective g →
injective (compose f g).
Proof.
(* FILL IN HERE *) Admitted.
Lemma surj_composition : ∀ {A B C} (f : A → B) (g : B → C),
surjective f →
surjective g →
surjective (compose f g).
Proof.
(* FILL IN HERE *) Admitted.
☐ 
surjective f →
surjective g →
surjective (compose f g).
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 1 star, optional (nat_natopt_inj)
Define a function nat_natopt : nat → option nat that is injective. Your definition and proof should be in Coq.
Definition nat_natopt_inj (n : nat) : option nat (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
Lemma nat_natopt_inj_correct : injective nat_natopt_inj.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Lemma nat_natopt_inj_correct : injective nat_natopt_inj.
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 2 stars (nat_natopt_bij)
Define a function nat_natopt_bij : nat → option nat that is bijective. Your definition and proof should be in Coq. It's okay if your solution is the same as for nat_natopt_bij.
Definition nat_natopt_bij (n : nat) : option nat (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
Lemma nat_natopt_bij_correct : bijective nat_natopt_bij.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Lemma nat_natopt_bij_correct : bijective nat_natopt_bij.
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 2 stars, optional (nat_inj)
Define a function nat_inj : nat → nat that is injective but not surjective.
Definition nat_inj (n : nat) : nat (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
Lemma nat_inj_injective : injective nat_inj.
Proof.
(* FILL IN HERE *) Admitted.
Lemma nat_inj_not_surjective : ~(surjective nat_inj).
Proof.
(* FILL IN HERE *) Admitted.
☐ 
Lemma nat_inj_injective : injective nat_inj.
Proof.
(* FILL IN HERE *) Admitted.
Lemma nat_inj_not_surjective : ~(surjective nat_inj).
Proof.
(* FILL IN HERE *) Admitted.
Exercise: 3 stars (bool_inj__surj)
Prove that a function f : bool → bool is injective iff it is surjective. Be patient with the case analysis!
Lemma bool_inj__surj : ∀ (f : bool → bool),
injective f ↔ surjective f.
Proof.
(* FILL IN HERE *) Admitted.
☐ 
injective f ↔ surjective f.
Proof.
(* FILL IN HERE *) Admitted.
There are three critical theorems about functions and inverses:
 
 
    For example, we know that the function square : non-negative real
    → non-negative real that squares non-negative real numbers has
    an inverse—namely, the square-root function. But simply having
    the square function and knowing that it's bijective isn't
    enough to magically create the square-root function! It's up to us
    to find some implementation that actually knows how to find square
    roots using, e.g., Newton's method.
-  If f : X → Y is injective, then there is a g : Y → X that
      is surjective.
-  If f : X → Y is surjective, then there is a g : Y → X that
      is injective.
- If f : X → Y is bijective, then there exists a g : Y → X that is also bijective and is an inverse of f.
Cardinality
       f
a1 |-> b1
a2 |-> b2
a3 |-> b3
a4 |-> b4
... 
a1 |-> b1
a2 |-> b2
a3 |-> b3
a4 |-> b4
...
-  every element of A gets mapped to a distinct element of B
      (injectivity), so |A| ≤ |B|;
- every element of B is accounted for in the mapping (surjectivity), so |B| ≤ |A|.
For example, we can define a set with two elements, two, and
    prove that it has the same cardinality as bool. To do so, we
    have to come up with a function that maps the elements of bool in
    a one-to-one and onto fashion, i.e., every element of bool is
    mapped to a distinct element of two and all elements of two
    are accounted for. 
Inductive two : Type :=
| column_a : two
| column_b : two.
Lemma bool_two_cardinality : same_cardinality bool two.
Proof.
| column_a : two
| column_b : two.
Lemma bool_two_cardinality : same_cardinality bool two.
Proof.
We'll have true map to column_a and false map to
      column_b. It doesn't really matter—we could have gone the
      other way. But we couldn't have had both true and false
      map to column_a, since that wouldn't be injective. 
  ∃ (fun b : bool ⇒ if b then column_a else column_b).
split.
- intros [] [] H.
+ reflexivity.
+ inversion H.
+ inversion H.
+ reflexivity.
- intros [].
+ ∃ true. reflexivity.
+ ∃ false. reflexivity.
Qed.
(* An absolute unit. Positively in awe at the size of this lad,
tt. *)
Print unit.
Lemma unit_bool_cardinality : ¬ (same_cardinality unit bool).
Proof.
intros [f [Hinj Hsurj]].
destruct (Hsurj true) as [[] Htrue].
destruct (Hsurj false) as [[] Hfalse].
rewrite Htrue in Hfalse. inversion Hfalse.
Qed.
☐ 
split.
- intros [] [] H.
+ reflexivity.
+ inversion H.
+ inversion H.
+ reflexivity.
- intros [].
+ ∃ true. reflexivity.
+ ∃ false. reflexivity.
Qed.
(* An absolute unit. Positively in awe at the size of this lad,
tt. *)
Print unit.
Lemma unit_bool_cardinality : ¬ (same_cardinality unit bool).
Proof.
intros [f [Hinj Hsurj]].
destruct (Hsurj true) as [[] Htrue].
destruct (Hsurj false) as [[] Hfalse].
rewrite Htrue in Hfalse. inversion Hfalse.
Qed.
Exercise: 3 stars, optional (nat__list_unit)
Prove that nat and list unit have the same cardinality. It will be easier to define your function outside of the lemma. Hint: your function will need to be recursive!-  Theorem: |nat| ≠ |nat → nat|.
Suppose, for a contradiction, that there exists a bijection f : nat → (nat → nat).Define g(n) = 1 + f n n. Since g : nat → nat and f is surjective, there exists some number m such that f m = g.What is g m? By the definition of g, we have g m = 1 + f m m. But we know that f m = g, so we really have g m = 1 + g m... an impossibility! We've reached a contradiction, so f must not be bijective. Qed.
Lemma nat_natfun_diag : ¬ (same_cardinality nat (nat → nat)).
Proof.
intros [f [Hinj Hsurj]].
unfold surjective in Hsurj.
remember (fun n ⇒ S ((f n) n)) as g.
destruct (Hsurj g) as [n Hf].
assert (∃ m, f n n = m). { ∃ (f n n). reflexivity. }
destruct H as [m Hfm].
assert (f n n = S m). { rewrite Hf. rewrite Heqg. rewrite Hfm. reflexivity. }
rewrite Hfm in H. apply n_Sn in H. destruct H.
Qed.
Proof.
intros [f [Hinj Hsurj]].
unfold surjective in Hsurj.
remember (fun n ⇒ S ((f n) n)) as g.
destruct (Hsurj g) as [n Hf].
assert (∃ m, f n n = m). { ∃ (f n n). reflexivity. }
destruct H as [m Hfm].
assert (f n n = S m). { rewrite Hf. rewrite Heqg. rewrite Hfm. reflexivity. }
rewrite Hfm in H. apply n_Sn in H. destruct H.
Qed.
Here's another example of the method, showing that |X| ≠ |P(X)|,
    i.e., a set and its powerset are of different cardinality. 
 
    I'll provide the Coq proof; you provide the informal proof.
 
Lemma set_powset_diag : ∀ {X}, ¬ (same_cardinality (set X) (set (set X))).
Proof.
intros X [f [Hinj Hsurj]].
unfold surjective in Hsurj.
remember (Spec (fun x ⇒ ¬ (Member x (f x)))) as A.
destruct (Hsurj A) as [e HA].
destruct (inclusion_exclusion A e) as [Hin | Hnotin].
- assert (¬Member e A) as Hnotin.
{ rewrite HeqA in Hin. apply member_spec_P in Hin .
rewrite <- HA. apply Hin. }
apply Hnotin. apply Hin.
- assert (Member e A) as Hin.
{ rewrite HeqA. apply P_member_spec.
rewrite HA. apply Hnotin. }
apply Hnotin. apply Hin.
Qed.
Proof.
intros X [f [Hinj Hsurj]].
unfold surjective in Hsurj.
remember (Spec (fun x ⇒ ¬ (Member x (f x)))) as A.
destruct (Hsurj A) as [e HA].
destruct (inclusion_exclusion A e) as [Hin | Hnotin].
- assert (¬Member e A) as Hnotin.
{ rewrite HeqA in Hin. apply member_spec_P in Hin .
rewrite <- HA. apply Hin. }
apply Hnotin. apply Hin.
- assert (Member e A) as Hin.
{ rewrite HeqA. apply P_member_spec.
rewrite HA. apply Hnotin. }
apply Hnotin. apply Hin.
Qed.
(* FILL IN HERE *)
☐ 
Countability
-  define a function f : X → nat and prove that f is injective
      (so |X| ≤ |nat|) 
- define a function g : nat → X and prove that g is surjective (so |X| ≤ |nat|)
Definition countable (X : Type) : Prop :=
(∃ f : X → nat, injective f) ∨
(∃ f : nat → X, surjective f).
Lemma bool_countable_surj : countable bool.
Proof.
right.
∃ (fun n ⇒ beq_nat n 0).
intros [].
- ∃ 0. reflexivity.
- ∃ 1. reflexivity.
Qed.
Lemma bool_countable_inj : countable bool.
Proof.
left.
∃ (fun b : bool ⇒ if b then 1 else 0).
intros [] [] H.
- reflexivity.
- inversion H.
- inversion H.
- reflexivity.
Qed.
(∃ f : X → nat, injective f) ∨
(∃ f : nat → X, surjective f).
Lemma bool_countable_surj : countable bool.
Proof.
right.
∃ (fun n ⇒ beq_nat n 0).
intros [].
- ∃ 0. reflexivity.
- ∃ 1. reflexivity.
Qed.
Lemma bool_countable_inj : countable bool.
Proof.
left.
∃ (fun b : bool ⇒ if b then 1 else 0).
intros [] [] H.
- reflexivity.
- inversion H.
- inversion H.
- reflexivity.
Qed.
Infinitely countable sets have the same cardinality as the
    nat—that is, we must exhibit a bijection.
 
    Our definition in Coq of infinite countability allows us to choose
    which direction our bijection points. Working informally, it
    doesn't matter, because bijections are invertible. But since Coq
    functions aren't automatically invertible, this definition makes
    our (formal) life easier.  
Definition infinitely_countable (X : Type) : Prop :=
same_cardinality X nat ∨ same_cardinality nat X.
same_cardinality X nat ∨ same_cardinality nat X.
We've already shown that list unit is infinitely countable. 
Corollary list_unit_infinitely_countable : infinitely_countable (list unit).
right. apply nat__list_unit.
Qed.
right. apply nat__list_unit.
Qed.
There are many surprising results in infinite countability.
 
    First, we can add a finite number of elements to any countable set
    and it will still be countable. For example, you've already shown that
    option nat is countable, in nat_natopt_bij_correct! 
Corollary natopt_infinitely_countable : infinitely_countable (option nat).
right. ∃ nat_natopt_bij. apply nat_natopt_bij_correct.
Qed.
right. ∃ nat_natopt_bij. apply nat_natopt_bij_correct.
Qed.
It's possible to add or subtract an infinite number of elements
    and still have an infinitely countable set. Here's proof that
    there as many nats as there are even nats.
 
    Let evens = {x:nat| evenb x}. To show |nat| = |evens|, we must
    define f : nat → evens and prove that f is bijective.
 
    We want a mapping like:
 
 
 
    So let f(x) = double x. We must show that f is bijective, i.e.,
    injective and surjective.
 
    We have f injective by double_injective.
 
    To see that f is surjective, let an even number m be given. We
    must show that there is some natural n such that f n = m. By
    even_bool_prop, we know that if m is even, then there exists a
    k such that m = double k, so let n be k.
  The argument underlying the previous proof is sometime called
    "Hilbert's Hotel", after the mathematician David Hilbert.
 
    Suppose an mathematical conference is being held at a hotel. There
    are countably infinitely many attendees, one per natural
    number. Fortunately, the hotel has a countably infinite number of
    rooms, so we just put the nth guest in the nth room.
 
 
 
    But what happens when another conference shows up at the hotel,
    this time with countably infinitely many computer scientists to
    crash the party? The hotel manager has a clever idea: switch it up
    so mathematicians are in every other room. There are now
    infintely many empty rooms for the CS folks!
 
 
 
    Hint: no need to be hyperformal here: if you know of an operation
    that works here but we haven't defined in Coq, you can use
    it. State the properties you assume.  
       f
0 |-> 0
1 |-> 2
2 |-> 4
3 |-> 6
4 |-> 8
... 
0 |-> 0
1 |-> 2
2 |-> 4
3 |-> 6
4 |-> 8
...
    0 |-> 0
1 |-> 1
2 |-> 2
3 |-> 3
... 
1 |-> 1
2 |-> 2
3 |-> 3
...
    0 |-> 0
??? 1
1 |-> 2
??? 3
2 |-> 4
??? 5
3 |-> 6
... 
 
??? 1
1 |-> 2
??? 3
2 |-> 4
??? 5
3 |-> 6
...
Exercise: 3 stars (evens_nat)
We've exhibited a bijection f : nat → evens to prove that |nat| = |evens|. Prove it the other way: exhibit a bijection g : evens → nat.
(* FILL IN HERE *)
☐ 
        0  1  2  3  ...
0 _ _ _ _
        
1 _ _ _ _
        
2 _ _ _ _
        
3 _ _ _ _
.
.
. 
0 _ _ _ _
1 _ _ _ _
2 _ _ _ _
3 _ _ _ _
.
.
.
        0  1  2  3  ...
0 0 2 5 9
        
1 1 4 8 _
        
2 3 7 _ _
        
3 6 _ _ _
.
.
. 
0 0 2 5 9
1 1 4 8 _
2 3 7 _ _
3 6 _ _ _
.
.
.
Exercise: 3 stars (countable_union)
- Theorem: S ∪ T is countable when S and T are countable.
(* FILL IN HERE *)
☐ 
Exercise: 3 stars, optional (countable_intersection)
This theorem is optional, but a nice partner for the foregoing lemma.- Theorem: S ∩ T is countable when S and T are countable.
(* FILL IN HERE *)
☐ 
Exercise: 4 stars (countable_product)
- Theorem: The product S × T = { (s,t) | s ∈ S ∧ t ∈ T } is countable when S and T are countable
(* FILL IN HERE *)
☐ 
Exercise: 2 stars (uncountable_complex)
The complex numbers are defined as the set complex = { a + b*i| a, b ∈ real }, where i is the square root of -1. Prove that the set complex is uncountable.
(* FILL IN HERE *)
☐ 
Exercise: 2 stars (uncountable_product)
If S is countable and T is uncountable, is S × T countable or uncountable? If it's always one or the other, prove it. Otherwise give an example of each.
(* FILL IN HERE *)
☐ 
Russell's paradox
-  Russell's paradox. Let the set X bedefined as the set of
    ordinary sets, i.e. X = { A | A is ordinary}, i.e., X = {A | A
    ∉ A}.
Is X ordinary or extraordinary? We find-  If X is ordinary, then X ∉ X. But then, by definition,
      every ordinary set should be a member of X... including
      itself! So then X ∈ X and X is
      extraordinary... contradicting our assumption that it was
      ordinary.
- If, on the other hand, that X is extraordinary, then X ∈ X. But X's members are exactly the ordinary sets, i.e., those A such that A ∉ A—so it's a contradiction to have X ∈ X.
 
-  If X is ordinary, then X ∉ X. But then, by definition,
      every ordinary set should be a member of X... including
      itself! So then X ∈ X and X is
      extraordinary... contradicting our assumption that it was
      ordinary.
-  First, Russell and Whitehead produced an incredible work,
      Principia Mathematica, which showed how to build up a theory
      of "ramified sets"—sets where a set of subdivisions or levels
      indicated which sets could be members of others. So began type
      theory—the underlying framework that Coq uses. Type theory has
      come a long way—_Principia is famously unreadable, full of
      opaque and tedious calculations to find simple facts like 1 + 1
      = 2. (It took them 352 pages to prove that fact!) Nothing like
      Coq, of course.
- Later, Ernst Zermelo and Abraham Fraenkel came up with a set of axioms for working with sets; they axioms are collectively called ZF. Rather than dealing with the tedium of ramified sets, they instituted an axiom called regularity (a/k/a the axiom of foundation) that prevents dangerous circularities (while still allowing heterogeneous sets):
  regularity : ∀ x, 
∃ a, a ∈ x →
∃ y, y ∈ x ∧ (¬∃ z, z ∈ y ∧ z ∈ x) 
∃ a, a ∈ x →
∃ y, y ∈ x ∧ (¬∃ z, z ∈ y ∧ z ∈ x)
