Here are the details of the proof we gave today that if ∣*A*∣ ≤ ∣*B*∣ and if ∣*B*∣ ≤ ∣*A*∣ that ∣*A*∣ = ∣*B*∣. This is called the Cantor-Schröder-Bernstein Theorem.

See Wikipedia for another writeup.

First a reminder of some relevant definitions:

A function

*f*:*A*→*B*is one-to-one if for all*x*_{1}and*x*_{2}∈*A*,*f*(*x*_{1}) ≠*f*(*x*_{2}) unless*x*_{1}=*x*_{2}. We will use the contrapositive definition:*f*is**one-to-one**if, for all*x*_{1}and*x*_{2}, if*f*(*x*_{1}) =*f*(*x*_{2}) then*x*_{1}=*x*_{2}.A function

*f*is**onto**if, for every*y*in the codomain, there is some*x*in the domain with*f*(*x*) =*y*.**∣**if there exists a function*A*∣ ≤ ∣*B*∣*f*:*A*→*B*that is one-to-one.**∣**if there exists a function*A*∣ = ∣*B*∣*f*:*A*→*B*that is both one-to-one and onto.

We will do a direct proof. Assume that ∣*A*∣ ≤ ∣*B*∣ and ∣*B*∣ ≤ ∣*A*∣. By definition, this means that there exists functions *f*: *A*→*B* and *g*: *B*→*A* that are both one-to-one.

Our goal is to piece these together to form a function *h*: *A*→*B* which is both one-to-one *and* onto.

To build the function *h*, we need to give its output on every input. To define it, we need to consider *chains* of elements that are formed by repeatedly applying *f* and *g*.

The chain of an element *x* ∈ *A* contains *x*, *f*(*x*), *g*(*f*(*x*)), *f*(*g*(*f*(*x*))), *g*(*f*(*g*(*f*(*x*)))) and so on. It also contains any elements that can be reached by going *backwards* along the chain. That is, if there happens to be some *y* such that *g*(*y*) = *x*, then *y* is in the chain.

There need not be such a *y* because *g* is not onto. However, if there is a *y*, it must be unique, because *g* is one-to-one. If such a *y* exists, we will call it *g*^{ − 1}(*y*). This discussion shows that *g*^{ − 1} is a partial function.

Similarly, the chain of *x* will include *f*^{ − 1}(*g*^{ − 1}(*x*)), *g*^{ − 1}(*f*^{ − 1}(*g*^{ − 1}(*x*))) and so on.

We want to distinguish between various types of chains, based on what happens as you walk backwards along them (that is, if we consider *x*, *g*^{ − 1}(*x*), *f*^{ − 1}(*g*^{ − 1}(*x*)), ... as defined above). There are 4 types:

- The chain forms a loop
- Chains that go "backwards" forever without repeating.
- Chains that stop in
*A*. That is, they end on some*x*with*g*^{ − 1}(*x*) undefined. - Chains that stop in
*B*.

Note that every element of both *A* and *B* is part of exactly one chain.

We define *h* as follows. If *x* is in a chain of type 1, 2, or 3, then we define *h*(*x*) = *f*(*x*). If *x* is in a chain of type 4, then we define *h*(*x*) = *g*^{ − 1}(*x*). *g*^{ − 1}(*x*) is defined, because if it wasn't, then *x* would be in a chain of type 3.

What's left is to show that *h* is one-to-one and onto.

We must show that whenever *h*(*x*_{1}) = *h*(*x*_{2}), that *x*_{1} = *x*_{2}. We will prove this directly: assume that *h*(*x*_{1}) = *h*(*x*_{2}). Notice that *h*(*x*) is always part of the same chain as *x*. Therefore, *x*_{1} and *x*_{2} must be in the same chain.

Let's consider the possible types of chains:

If the chain of

*x*_{1}and*x*_{2}is of type 1, 2, or 3, then*h*(*x*_{1}) =*f*(*x*_{1}) and*h*(*x*_{2}) =*f*(*x*_{2}). Therefore,*f*(*x*_{1}) =*h*(*x*_{1}) =*h*(*x*_{2}) =*f*(*x*_{2})

Since*f*is one-to-one, this implies that*x*_{1}=*x*_{2}as required.If the chain is of type 4, then we have that

*h*(*x*_{1}) =*y*_{1}with*g*(*y*_{1}) =*x*_{1}, and*h*(*x*_{2}) =*y*_{2}with*g*(*y*_{2}) =*x*_{2}. Since*h*(*x*_{1}) =*h*(*x*_{2}), we have*y*_{1}=*y*_{2}, so*x*_{1}=*g*(*y*_{1}) =*g*(*y*_{2}) =*x*_{2}

as required.

In any case, we have shown that *x*_{1} = *x*_{2}, so we conclude that *h* is one-to-one.

Given an arbitrary *y* ∈ *B*, we must find some *x* ∈ *A* with *h*(*x*) = *y*. We consider the chain containing *y*.

If that chain is of type 1, 2, or 3, then we know there is some

*x*such that*f*(*x*) =*y*. Since*x*and*y*are in the same chain, we have that*x*'s chain is of type 1, 2 or 3, so*h*(*x*) =*f*(*x*) =*y*.If the chain is of type 4, then we know that

*g*(*y*) is also in a chain of type 4. That means that*h*(*g*(*y*)) =*y*. Therefore there is some*x*(namely*g*(*y*)) that maps to*y*.

In either case, we have found an element that maps to *y*, so *h* is onto.

We have defined a function *h*: *A*→*B* and shown that it is both one-to-one and onto. Therefore (by definition) ∣*A*∣ = ∣*B*∣.