• Tutorial

# Introduction

Last time we got acquainted with the basic concepts of the theory of topological spaces, and also examined the class for representing finite topological spaces written in Java. Today we move on, study the concept of a topology base and get an idea of ​​what it is needed for, and also define the concept of continuous mapping of topological spaces. The latter is of main interest because there is no concept of the distance between objects in topological space , but nevertheless we can describe in a formal language a sufficient proximity of objects in terms of ... Well, by the way, you will find out a little later.

# Topology base

Before we go any further, I would like to ask you the following simple question.

Exercise 0. Let X be the set of n elements. How many elements does the discrete topology m containing all subsets of the set X contain?

Obviously, the answer will be 2 n .
If we used the class described in the previous article to create a discrete topology on a set of 10 elements, then we would need to add 1024 sets to the topology: quite a lot of routine work, don’t you find?

But with the help of the database, it’s enough for you to specify only 10 sets instead of 1024. And if your topology is not discrete, then even less.

So, let's move on to the definition. There are several equivalent definitions of a topology base. I will give as the main definition used in the Kolmogorov school, and then I will prove the equivalence of another definition.

Definition 1. A collection J of open subsets of a set X is called a topology base if every open subset G of the space (X, m) can be represented as the union of some collection of sets from J.

From a mathematical point of view, this definition is quite understandable, however, programming it is quite nontrivial task. The situation is complicated by the fact that the set G does not have to be a union of two sets of the base, it can be a union of three, four, and so on.

Fortunately, the case will help simplify the following theorem.
Theorem 1. For the system J to be the base of the topology, it is necessary and sufficient that for every open set G and for every point x in G there exists a set G (x) belonging to J and containing x such that G (x) is a subset of the G .

The proof of the theorem is also quite simple. First, we prove the sufficiency of the condition. This means that if the written condition is satisfied, then J will be the base of the topology.
But if it is satisfied, then G can be represented as the union over all x of G of the sets G (x), i.e., the condition from the definition is satisfied, and J is the topology base.
The necessity of a condition means that if J is a base, then our condition is true. But if J is a base, then any open set is representable as a union of sets from J, from which the condition immediately follows.

This theorem already helps to program better the algorithm for determining whether a given system of subsets is a base, however, it is somewhat difficult here that the first quantifier of a condition is the universal quantifier.

And this means that when designing the algorithm, we must go from the opposite: first we consider that our system is the base, and we change the solution if the opposite statement is true.

In mathematics, the treatment of such conditions is as follows: the universal quantifier is replaced by the existential quantifier and vice versa, and the predicate is replaced by the inverse.

Therefore, the algorithm written in natural language will sound as follows:

1. We consider that the argument of the method is the basis of topology.
2.If there exists an open set G and a point x from G such that any set G from the method argument containing x is NOT a subset of G, then return FALSE, otherwise return TRUE.

``````public boolean isBase(FSet> mbbase)
{
boolean flag = true;
Node t = first;
while (t != null && flag)
{
FSet open = t.elem;
FSet.Node openNode = open.first;
boolean isSubsetOpen = true;
while (openNode != null && isSubsetOpen)
{
Integer x = openNode.elem;
Node baseNode = mbbase.first;
boolean forall = true;
while (baseNode != null && forall)
{
if (baseNode.elem.contains(x) && baseNode.elem.subset(open))
forall = false;
baseNode = baseNode.next;
}
if (forall)
{
flag = false;
isSubsetOpen = false;
}
openNode = openNode.next;
}
t = t.next;
}
return flag;
}
``````

Now create a small class for the base
``````public class Base extends FSet>{
public Base()
{
super();
}
}
``````

This is necessary in order to be able to write a base topology constructor.

If we wrote just FSet, you would get the following error from the compiler: Erasure of method is the same as another method, since we already have a constructor with FSet parameters. This is a feature of the Java language.

And to add the system to the topology is quite easy, just add some private methods. But before, simple tasks.

Problem 1. Let X be a set of cardinality n, and m the discrete topology defined on this set. Find the topology base.

``````private void uniteAll()
{
for (Node p = first; p != null; p = p.next)
{
for (Node q = first; q != null; q = q.next)
}
}
private void intersectAll()
{
for (Node p = first; p != null; p = p.next)
{
for (Node q = first; q != null; q = q.next)
}
}
public Topology(Base base)
{
for (Node p = base.first; p != null; p = p.next)
boolean isTpl = isTopology();
while (!isTpl)
{
uniteAll();
intersectAll();
isTpl = isTopology();
}
}
``````

The topology base is made up of all singleton subsets: {{1}, {2}, ..., {n}}

If we talk about the general topology, then a fairly important class of topological spaces are spaces with a countable base. They are also called spaces with the second axiom of countability.

It is easy to notice that finite topological spaces, namely, we program them, form a subset of all spaces with the second axiom of countability.

But if this is the second axiom of counting, then there must be the first, right? We will deal with it now, and then plunge into continuous mappings.

# Defining neighborhood systems

Definition 2. Let for a point x of a topological space X there exist no more than a countable system of neighborhoods {O n (x)} such that for every open set G containing x there is a neighborhood O n (x) contained in G. This the system is called the determining system of neighborhoods of the point x.

Definition 3. If for each point x there exists its defining system of neighborhoods, then the space satisfies the first axiom of countability.

This definition is of greater interest in the framework of the general topology than in the final topologies that are currently being considered, since such a system can simply be taken as the system of all neighborhoods of a given point. However, even here you can raise one interesting question, which I will kindly provide to you.

Problem 3. Give an example of a finite topological space in which the determining system of neighborhoods of a point lies strictly inside the system of all neighborhoods of a given point.

``````public boolean isFundamentalSystem(int x, ArrayList> neighbourhoods)
{
boolean flag = true;
Node t = first;
while (t != null && flag)
{
FSet open = t.elem;
if (open.contains(x))
{
int i = 0;
boolean isSubset = false;
while (i < neighbourhoods.size() && !isSubset)
{
if (neighbourhoods.get(i).subset(open))
isSubset = true;
i++;
}
if (!isSubset)
flag = false;
}
t = t.next;
}
return flag;
}
``````

Let X = {1,2,3,4}, m = {Ø, {1}, {3}, {2,4}, {1,3}, {1,2,4}, {2,3 , 4}, {1,2,3,4}}.

The system {{3}} is the determining system of a neighborhood of point 3.

# Continuous Mappings

So we came to the most interesting place in our today's lecture. To continuous mappings.

Basically, Java already has an interface for mappings: Mapper , however, because it contains two methods, it cannot be used as a functional interface.

I use Java 8, and I would like to write mappings in a more convenient way than creating a class that implements an interface and so on. If your development environment does not support Java 8, then the method code will still work, but the call code will have to be changed.

So, I will create the following simple interface
``````@FunctionalInterface
public interface Mapping {
Integer f(Integer x);
}
``````

The abstract above is optional, but it will give an error if you add another abstract method to the interface.

Now we turn to the mathematical side of the issue and give the concept of continuity in terms of neighborhoods of a point.

Definition 4. Let (X, т1) and (Y, т2) be two topological spaces. A mapping f of the space X to the space Y is called continuous at the point x 0 if for any neighborhood U y 0 of the point y 0 = f (x 0 ) there is a neighborhood V x 0 of the point x 0 such that f (V x 0 ) is contained inside U y 0. A mapping f is called continuous if it is continuous at every point.

If this is translated into Russian, then the definition of continuity at a point will sound something like this: Whatever neighborhood of the image of a given point we take, there is a neighborhood of this point that the image of this neighborhood will lie inside the neighborhood of the image of the point.

Wait a minute ... If we recall the beginning of the analysis, we will get exactly the definition of Cauchy function continuity, with the only difference being that we left the epsilon-delta language and replaced the partial order relation in determining proximity.

But not everything is so simple here. Therefore, I offer you an interesting puzzle.
Problem 4. Let X be a topological space with base {{1}, {2,4}, {1,2,3,4}}, Y be a base with {{1}, {3}, {1,2, 3.4}}.
Consider the identity map f from X to Y acting by the rule f (x) = x. Is it continuous? If so, prove it. If not, show at what point it breaks.
The same question applies to the mapping f from Y to X, acting by the rule f (x) = x.

``````public boolean isContinuous(Mapping f, Integer x0, Topology Y)
{
boolean flag = true;
int y0 = f.f(x0);
ArrayList> Uy0 = Y.getNeighbourhoods(y0);
ArrayList> Vx0 = getNeighbourhoods(x0);
int i = 0;
while (i < Uy0.size() && flag)
{
int j = 0;
boolean subset = false;
while (j < Vx0.size() && !subset)
{
FSet image = new FSet<>();
for (FSet.Node p = Vx0.get(j).first; p != null; p = p.next) {
}
if (image.subset(Uy0.get(i)))
subset = true;
j++;
}
if (!subset)
flag = false;
i++;
}
return flag;
}
``````

This time I will give you the execution code:

``````package generaltopology;
import java.util.*;
public class FSetDemo {
public static void main(String[] args) {
Base baseX = new Base();
FSet x = new FSet<>();
FSet a = new FSet<>();
FSet b = new FSet<>();
FSet c = new FSet<>();
Base baseY = new Base();
Topology tau = new Topology(baseX);
System.out.println(tau);
Topology tau2 = new Topology(baseY);
System.out.println(tau2);
for (int i = 1; i <= 4; i++)
{
System.out.print(tau.isContinuous(u -> u, i, tau2) + " ");
}
System.out.println();
for (int i = 1; i <= 4; i++)
{
System.out.print(tau2.isContinuous(u -> u, i, tau) + " ");
}
}
}
``````

As you can see, the use of a lambda expression is quite justified here, since it allows you to specify the rule for mapping one space to another quite accurately.

And, as I promised, the answer is: