LANGUAGES AND STRINGS:
Why do we bother to study the theory of computation?
- The Theory of Computation is the study of the fundamental capabilities and limitations of computers. It’s not just about learning how to code in a specific language, rather, it’s about asking and answering abstract questions such as:
- “What can and cannot be computed?” are there problems that are IMPOSSIBLE for any computer to solve, no matter how powerful it is?
- “How efficiently can a problem be solved?” so if a problem CAN be solved, how much memory or time will it take?
So, we learn the fundamental rules and limits of what computers can and can’t do. This knowledge lasts forever, hence why it’s important to study the theory of computation, so if a new programming language emerges, we have some knowledge about its limitations and capabilities
So, you basically start asking yourself “Can my language do this?” and ask “Is this POSSIBLE to do, and if so, what is the best possible performance I can achieve?”
In order to process a program, a computer has to solve several problems, all based on strings of characters. It gets broken down into:
- Lexical Analysis: Break the code into pieces, basically break them into variables and numbers
- Parsing: Create a tree that corresponds to the sequence of operations that should be executed
- Optimization: Make the code faster or simpler
- Termination: Can we prove the program will ever stop?
- Interpretation: Actually running the program and see what it does
So, this problem:
int alpha, beta;
alpha = 3;
beta = (2 + 5) / 10;
can be broken down into this tree:
In order to study all these different problems, we need one common way to talk about them. That framework is called Language Recognition
A language is a set of strings over an alphabet
STRINGS:
A string is a finite sequence of symbols drawn from some alphabet. A string can be empty, we define this with (epsilon)
- an example of a string is something like 001 or cat
An alphabet is a finite, non empty set of symbols. An alphabet is usually defined with . An alphabet CANNOT be infinitely large
- an example of alphabets can be a binary alphabet, which is just the set
we denote as the set of ALL possible strings over an alphabet
-
for example, if our alphabet was , then
FUNCTIONS ON STRINGS:
Length: is the number of symbols (characters, letters) in
- for example, or ,
is the number of times that occurs in
- for example, is basically saying how many ’s are there in the sequence ?
Concatenation: stick two strings together basically
- example, if and , then , you just stick them together
usually we denote the concatenation of two strings by but if you see don’t start shitting your pants they mean the same shit
PROPERTIES:
-
The length of
- take the goodbye example: and
-
The empty string is the identity:
- btw, an identity is basically an element that, when combined with any other element using a specific operation, leaves the other element unchanged. so, when you do 100 + 0 = 100, 0 is the identity here. Or if you do 100 x 1 = 100, 1 is the identity here
-
It’s associative, meaning:
-
example: let . If we do the left side first, we will get
now if we do the right side: , you get the same thing!
-
-
They are NOT commutative, so doing will not give you the same results in strings
-
example: if and , if we do , but if we do
, they arent the same clearly
-
Repetition (Power): means that the string is repeated times
- example: (anything to the power of 0 is the empty string)
Reverse: For each string , is just the string written backwards
The reverse of is just
- if then
- if then:
- so, we define
OR IF THE SECOND THING DOESNT MAKE SENSE:
For a long string, take the first character and put it at the end of the reverse of the rest.
- example:
THEOREM: The reverse of two concatenated strings is the reverse of the second string followed by the reverse of the first, given are strings
Example:
(remember to come back here because there’s the whole proof by induction thing but i need to look more into it)
RELATIONS ON STRINGS:
Substring: A string that appears consecutively inside another string
For example:
- IS a substring of the string
- IS NOT a substring of the string (there are no consecutive ’s inside the string)
EVERY STRING IS A SUBSTRING OF ITSELF
is a substring of every string
What is the difference between a substring and a proper substring?
- a substring is any consecutive sequence of characters taken from within the string, this includes:
- the string ITSELF
- the empty string
- any consecutive sequence at the beginning, middle, or end
- example: for the string , all of its substrings are:
- a proper substring is any substring that DOES NOT INCLUDE THE STRING ITSELF
- example: for the string , all of the proper substrings include:
- example: for the string , all of the proper substrings include:
Prefix: A string you can put at the beginning of another string to build it
is a prefix of if you can add something to the end of to get
EVERY STRING IS A PREFIX OF ITSELF
is a prefix of every string
What is the difference between a prefix and a proper prefix?
- a prefix is the consecutive sequence of characters staring from left to right that INCLUDES the string
- example: for the string , the prefixes of are:
- example: for the string , the prefixes of are:
- a proper prefix is basically all prefixes EXCEPT FOR THE ENTIRE STRING
- example: for the string , the proper prefixes are:
- example: for the string , the proper prefixes are:
Suffix: A string you can put at the end of another string to build it
is a suffix of if you can add something to the start of to get
EVERY STRING IS A SUFFIX OF ITSELF
is a suffix of every string
What is the difference between a suffix and a proper suffix?
- a suffix is the consecutive characters starting from right to left that INCLUDES the string
- example: for the string , the suffixes are:
- example: for the string , the suffixes are:
- a proper suffix is basically all suffixes EXCEPT FOR THE ENTIRE STRING
- example: for the string , the proper suffixes are:
- example: for the string , the proper suffixes are:
DEFINING A LANGUAGE:
A language is a (finite or infinite) set of string over a finite alphabet
Examples: Let
Some languages over include:
- , and many more!
The language contains an infinite number of string, including:
It is important to know that , HAS 1 string, but it just happens to have no letters, its just empty
If we say that , this would mean the contents of would be letters or symbols
If we say that , this would mean the contents of would be STRINGS
- so, , this means the contents are called letters
- , there are all STRINGS
Some examples to make stuff more clearer:
So:
- ARE IN L. While bb may seem like it wouldnt be there, since there are no a’s in the string, you are allowed to just put b’s, the string just happens to have zero a’s which is fine, there is no restriction on saying there HAS to be an a
- are NOT in L. in the first and second one, we have an a after a b, and in the last one we have a c which is not even supposed to be there? who invited the horse
- ARE IN L.
So:
- To translate this into simpler terms, this is essentially saying that the string HAS to end with an
- So, ARE IN L
- are NOT in L
What are the following languages?
- this can be:
- this can be:
- this one is a bit tricky. is a prefix of every string, and does NOT start with . So, this means
You can use repetition in a language definition:
LANGUAGES ARE SETS:
There are two main ways to computationally handle a language
- Generator (enumerator): A machine that LISTS OUT all the strings in the language, one by one
- Recognizer: A machine that takes a string as input and answers “yes” if string in language, if not, then the answer would be a “no”. obviously, this would be more useful
ENUMERATION:
How do they list strings?
The usually list them in lexicographic order (dictionary order essentially, shortest first)
- ,
Example, the lexicographic enumeration of:
would be:
HOW LARGE IS A LANGUAGE:
We know that the smallest possible language is the empty set , which has ZERO strings
We also know that the largest possible language is , which contains every possivle string, which would make that language infinitely large
There is a theory that states:
If , then is countably infinite
Now, what the HELL does this mean?
- Let us say you have an alphabet with just two letters , this includes:
- All 1-letter words (cause of enumeration)
- All 2-letter words (also, cause of enumeration)
- All 3-letter words, and so on, FOREVER!
But, this seems impossible to count, because there is no end! the trick here is to create a list that will eventually include every possible word
So, we sort the words by LENGTH first. Then, in each list, list them in alphabetical order
It would look like:
- Length 0:
- Length 1:
- Length 2:
- Length 3:
- Length 4, you get the gist, and so on
Now, why is this list countably infinite?
- It’s a list: meaning you can number EVERY item. The first word is number 1, the epsilon , the second word is number 2 (a), the third is number 3 (b), and so on
Due to this sorting rule, every single possible string will eventually appear in the list and get assigned its own unique number. Since you can pair each string with a unique number, the set of all strings is the same size as the set of natural numbers, which makes it countably infinite
countably infinite just means you can make an infinite list of something
- every single item in the set can be given a unique number, and every number on your list will have an item
Another theorem states:
If then the set of languages over is uncountably infinite
Uncountably infinite means there are so many things that is impossible to make a list of all of them. Even an infinite list would miss something
Example:
Think of a 1-centimeter line segment. It begins at 0cm and ends at 1cm
Now, think about how many points are on that line. A point is a specific, exact location, like 0.5cm or 0.5000000000001cm
The number of points between 0 and 1 is uncountably infinite. The reason why you can’t list them is because:
Let us say you try to make a list of EVERY point. It might start like:
- 1: 0.1cm
- 2: 0.01cm
- 3: 0.001cm
- 4: 0.00001cm
- you plan to list… quite a lot
You will never, never list the point 0.5cm because you’re listing numbers that just get infinitely closer and smaller towards zero.
So, the set of all points on a line is uncountably infinite. There is no possible way to put them in order and assign each one a number. There are simply too many
All in all, uncountably infinite means that a set is so vast that its impossible to create a complete, numbered list of all elements, making it a larger type of infinite than the infinity of whole numbers (woah..)
DIAGONALIZATION
We know that integers and rational numbers are countable, however, irrational numbers are uncountable.
Proof:
-
Suppose the irrational numbers WERE countable, we could list them as:
-
Construct a new number N by ensuring:
Its 1st decimal digit ≠ the 1st decimal digit of
Its 2nd decimal digit ≠ the 2nd decimal digit of
Its 3rd decimal digit ≠ the 3rd decimal digit of
…and so on
-
By construction, differs from every in at least one decimal place
-
So, is NOT on the list, which leads to a contradiction
-
Therefore, irrationals cannot be listed (they are uncountable)
Let me give a more solid example with numbers so it makes sense:
FUNCTIONS ON LANGUAGES:
Since languages are sets, we can use set operations on them:
- Union
- Intersection
- Complement
We also have special language operations:
- Concatenation
- Kleene Star
CONCATENATION:
Concatenation is NOT communitive (a cat b != b cat a all the time)
If and are languages over , then:
So, combine every string in the first language with every string in the second
Example:
The language is like the number 1 for multiplication. Concatenating anything with gives you the original thing back
The empty language is like the number 0 for multiplication. Concatenating anything with gives you
When defining languages with variables like and in , the variables are independent
For example:
We are given and
Concatenating these two means: take one string from and put it directly in front of one string from
So:
example:
, obviously, they are both independent
KLEENE STAR:
The Kleene star operation basically means “zero or more concatenations of strings from ”
This always includes
It includes every string that can be formed by concatenating any finite number of strings from
Example:
PLUS OPERATOR:
The plus operation means “one or more concatenations of strings from ”
iff . If , then still contains because you could choose it from one of the concatenations
When we say “ is the closure of under concatenation”, this means:
- contains all strings that can be formed by concatenating one or more strings from
- It’s the smallest set with that property
CONCATENATION AND REVERSE OF LANGUAGES
The reverse of the concatenation of two languages is the concatenation of their reverses, but in the opposite order
Proof:
We know that
- is the set of all reversed strings where and
- This equals the set:
- This set is exactly
Example:
Suppose and over the alphabet
Let us calculate
First, find the concatenation of the two languages
Now, let us reverse this new language:
So,
Let us calculate
Now, concatenate the two:
They are the exact same!
SEMANTIC VS SYNTAX:
The distinction between the form of a string (syntax) and its meaning (semantics)
For example, the language . While this language is well defined syntactically, what do these strings mean semantic wise? On their own, they are just patterns
Syntax: The formal structure, rules, and patterns of strings in a language
Semantics: The meaning assigned to those strings
DECISION PROBLEMS:
A decision problem is any problem that has a yes/no answer
A decision procedure is an algorithm that solves a decision problem (always halts with the correct answer)
For example:
- An decision problem could be “is integer a prime” and the decision procedure can be some algorithm that checks if is prime or not
Our main focus will be:
The language recognition problem: Given a language and a string , is
ENCODING:
Problems that don’t look like decision problems can be recast into new problems that do look like it. EVERYTHING is a string
Example:
“Does a program always halt?” can be recast as a decision problem, which would look like: “Given a program , written in some standard programming language, is guaranteed to halt on all inputs?”
The language to be decided:
, obviously, halts IFF
Convention:
<X> represents the string encoding of the object X
<X,Y> represents the string encoding of the pair objects X and Y
Another example:
You can transform a function computation problem into a verification problem
Original problem: Compute the product of two integers
Recast as decision: Instead of computing x * y, verify if a given answer z is correct
Language to be decided:
so it would basically be:
L = { x * y = z such that integer_3 = int_1 x int_2 }. if int 1 times int 2 is not int 3, then it isn't in the language
- so , but
Languages and machine
-
SD: Semi-Decidable (Countable infinite)
-
D: Decidable Languages (Countable infinite)
-
Context-Free Languages:
- FSMs: Finite State Machines (Finite Automata)
- All Compilers are here
-
Regular Languages:
- PDAs: Pushdown Automata(s)
Claim: Everything outside SD is impossible to say anything about it (Will be proved later)
Rule of Least Power:
- This is the way to tackle each problem in the course? (I guess)
Turing machines
- Turing machines have a tape that they can read and write stuff on by moving the head pointer (the arrow in this picture)
Grammars, Languages, and Machines
Examples of each
- Grammar: Generate any possible code in C++
- Machine (Compiler): Get that code and tell you if it is syntactically correct.
- Language: Creates the strings used throughout the program (fact check cause idk)