Automata
Homeworks for the
course CS 3350, Fall 2023
General comment. The main purpose of most homeworks is to
show how well you understand the algorithms.
In many cases, the resulting finite automata, pushdown automata,
and Turing machines can be simplified, but please first
literally apply the algorithm so that we know that you can use
it.
If in addition to this, you also show how to make the
corresponding Turing machine or finite automaton or whatever more
concise, nothing wrong with that, the TA may even give you some
extra points (if she has time to grade these additional things).
But the most important thing is to show that you can follow the
algorithm.
For simple examples that we give you as homeworks:
- you
may immediately see how to convert, e.g., a context-free grammar
into a Chomsky normal form,
- but if someone gives you a more
complex case, you will have to use the algorithm.
So, it is
important to learn how to follow the algorithm.
If you deviate from the algorithm, how do we know that you learned
the algorithms? It was the same with sorting.
- Of course,
if someone gives you a list of 4 numbers on the test, you can sort
them yourself easily.
- The purpose of the question was that you
show that you understand mergesort, quicksort etc., not that
you sort 4 numbers.
In general: - If after you
show that you understand the algorithm you also provide a simpler
answer -- great,
- but not instead of following the
algorithm.
1. (Due September 6) In class, we designed automata for
recognizing integers and real numbers.
1.1. Use the same ideas to describe an automaton for recognizing
proper names. For simplicity, assume that a name should start with
a capital letter -- either by itself or followed by lowercase
letters. For example, J is a proper name and Ale is a proper name,
but ale1 is not a proper name.
A natural idea is to have 3 states: start (s), is a proper name
(p), error (e). Start is the starting state, p is the only final
state. The transitions are as follows:
- from s, any
capital letter A, ..., Z leads to p, every digit 0, ..., 9 and
every lowercase letter a, ..., z leads to e;
- from p, any
lowercase letter leads back to p, every other symbol leads to e;
- from e, every symbol leads back to e.
1.2. Trace, step-by-step, how the finite automaton from Part 1.1
will check whether the following two words (sequences of symbols)
are proper names:
- the word Ale (which this automaton
should accept) and
- the word ale1 (which this automaton should
reject).
1.3. Write down the tuple <Q, Σ, δ, q0,
F> corresponding to the automaton from Part 1.1:
- Q is
the set of all the states,
- Σ is the alphabet, i.e., the
set of all the symbols that this automaton can encounter; for
simplicity, consider only four symbols: 0, 1, and letters a and A;
- δ: Q x Σ → Q is the function that describes,
for each state q and for each symbol s, the state δ(q,s) to
which the automaton that was originally in the state q moves when
it sees the symbol s (you do not need to describe all possible
transitions this way, just describe two of them);
-
q0 is the starting state, and
- F is the set of all
final states.
1.4. For each automaton A, let LA denote
the language of all the words accepted by this automaton, i.e., of
all the words for which this automaton ends up in a final state. In
class, we learned a general algorithm that:
- given two
automata A and B that correspond to languages
LA and LB,
- constructs two new
automata for recognizing, correspondingly, the union and
intersection of languages LA and
LB.
Apply this algorithm to the following
two automata: - the automaton from Part 1.1 as Automaton
A, and
- an automaton for recognizing Java names for
classes as Automaton B.
In Java, a name of the class
should start with a capital letter, all other symbols can be
letters or digits. A natural idea is to have 3 states: start (s),
correct name (c), and error (e). Start is the starting state, c is
the only final state. The transitions are as follows: -
from s, any capital letter lead to c, any other symbol leads to e;
- from c, any symbol leads back to c;
- from e, every symbol
leads back to e.
For simplicity, in your automaton for
recognizing the union and intersection of the two languages, feel
free to assume that you only have symbols 0, 1, a, and A.
Solutions to Problem 1
2. (Due September 13)
- Use the general algorithm
that we learned in class to design a non-deterministic finite
automaton that recognizes the language a(a U b)*b of all the words
that start with a, contain only letters a and b and that end in b:
- a and b are languages consisting of only one 1-symbol
word each: a is a language consisting of a single 1-symbol word a;
b is a language consisting of a single 1-symbol word b;
- for
any two languages C and D, the notation CD means concatenation;
- transform the resulting non-deterministic finite
automaton into a deterministic one.
Solutions to Problem 2
3. (Due September 13) Apply the general algorithm for
transforming the finite automaton into a regular language (i.e., a
language described by a regular expression) to Automaton B from
Problem 1.4. For simplicity, assume that we only have symbols 0, 1,
a, and A. Eliminate first the error state, then the start state,
and finally, the state c.
Solutions to Problem 3
4. (Due September 20) Write and test a method that simulates
a general finite automaton. Your program should enable the computer
to simulate any given finite automaton and then to simulate, for
any given word, step-by-step, how this automaton decides whether
this word is accepted by the automaton.
The input to this method should include the full description of the
corresponding finite automaton:
- the number N of states;
these states are q0, ..., qN − 1; we
assume that q0 is the start state; for simplicity, we
describe the states by the corresponding integers 0, ..., N;
- the number M of symbols; these symbols are s0, ...
sM − 1; for simplicity, we describe the symbols by
the corresponding integers 0, ..., M;
- an integer array
state[n][m] whose elements describe to what state the finite
automaton moves if it was in the state qn and sees the
symbol sm; and
- a boolean array final[n] whose
elements describe, for each state qn, whether this state
is final or not.
When simulating a finite automaton, your
program needs to keep track, at each moment of time, of the current
state. Initially, the state is q0 -- which is described
by number 0.
Turn in:
- a file containing the code of the method, and
- a file containing the result of testing this method.
If
you used any auxiliary program to test your method, also submit a
file containing the code of this auxiliary program. Feel free to
use Java, C, C++, Fortran, or any programming language in which the
code is understandable.
5. (Due September 20) A student who only has As and Bs has a
GPA higher than 3.5 if and only if this student has more As than
Bs. Prove that the following language is not regular: the set L of
all sequences of As and Bs that correspond to students with GPA
higher than 3.5.
Solutions to Problem 5
6. (Due September 20) Show, step by step, how the following
pushdown automaton -- that checks whether a word consisting of
letters A and B corresponds to a student with GPA higher than 3.5
-- will accept the word ABAA. This pushdown automaton has three
states:
- the starting state s,
- the working state w,
and
- the final state f.
In the stack, in addition to the
bottom symbol $, we have: - either one or several As --
indicating how many more As than Bs the student has,
- or one or
several Bs -- indicating how many more Bs than As the student
has.
The transitions are as follows: - From s to w, the
transition is ε, ε → $.
- From w to f, the
transition is: ε, A → ε.
- From f to f, we
have two transitions: ε, A → ε and ε,
$ → ε.
From w to w, we have the following
transitions: - If we see the symbol A and $ is on top of
the stack, we keep the dollar sign and add A to the stack, i.e., we
have transition A, $ → $ that brings us to an intermediate
state a1, and then the transition ε, ε
→ A that brings us back to the working state.
- If we see the symbol A and A is on top of the stack, we keep
the top A and add another A to the stack, i.e., we have transition
A, A → A that brings us to an intermediate state
a2, and then the transition ε, ε →
A that brings us back to the working state.
- If we see the symbol A and B is on top of the stack, we delete
the top B, i.e., we have transition A, B → ε.
- If we see the symbol B and $ is on top of the stack, we keep
the dollar sign and add B to the stack, i.e., we have transition B,
$ → $ that brings us to an intermediate state a3,
and then the transition ε, ε → B that brings
us back to the working state.
- If we see the symbol B and B is on top of the stack, we keep
the top B and add another B to the stack, i.e., we have transition
B, B → B that brings us to an intermediate state
a4, and then the transition ε, ε →
B that brings us back to the working state.
- If we see the symbol B and A is on top of the stack, we delete
the top A from the stack, i.e., we have transition B, A →
ε.
Solutions to Problem 6
7. (Due September 20 for extra credit, due September 27 for
regular cradit) Show, step by step, how the following grammar
describing simple arithmetic expressions will generate the
expression 2 + 3 * 4. In this grammar, D stands for digit, E stands
for expression. The rules are: D → 0, ..., D → 9, E
→ D, E → E + E, E → E * E.
Solutions to Problem 7
8. (Due September 27) In the corresponding lecture, we
described an algorithm that, given a finite automaton, produces a
context-free grammar -- a grammar that generate a word if and only
if this word is accepted by the given automaton.
- On the
example of the automaton B from Homework 1.4, show how this
algorithm will generate the corresponding context-free grammar.
Similarly to Homework 3, assume that we only have symbols 0, 1, a,
and A.
- On the example of the word A1a accepted by this
automaton, show how the tracing of acceptance of this word by the
finite automaton can be translated into a generation of this same
word by your context-free grammar.
Solutions to Problem 8
9. (Due September 27) Use a general algorithm to construct a
(non-deterministic) pushdown automaton that corresponds to
context-free grammar described in Problem 7. Show, step by step,
how the word 2 + 3 will be accepted by this automaton.
Solutions to Problem 9
10. (Due September 27) Transform the grammar from Homework 7
into Chomsky normal form. Assume that we are only using digits 0
and 1.
Solutions to Problem 10
11. (Due October 4) Use the general algorithm to transform
the pushdown automaton from Problem 6 into a context-free grammar.
Show, step-by-step, how the resulting grammar will generate the
word ABAA.
Solutions to Problem 11
12. (Due October 18) For the grammar described in Homework
7, show how the word 2 + 3 * 4 can be represented as uvxyz in
accordance with the pumping lemma for context-free grammars. Show
that the corresponding word uvvxyyz will be generated by this
grammar.
Solutions to Problem 12
13. (Due October 18) Three chess players a, b,
and c of almost equal strength play in a tournament. After
each game, we record who was the winner. The number of games won by
a is exactly 1 larger than the number of games one by
b, and the number of games won by c is 1 smaller than
the number of games won by b. An example of such sequence is
abcaba: a won 3 games, b won 3 − 1 = 2
games, and c won 2 − 1 = 1 game. Prove that the
language of all such sequences is not context-free.
Solutions to Problem 13
14. (Due October 18) Show, step by step, how the stack-based
algorithm will transform the expression (1 + 4) * (9 − 2)
into a postfix expression, and then how a second stack-based
algorithm will compute the value of this postfix expression.
Solutions to Problem 14
15. (Due October 25) Design a Turing machine that, given a
unary number n which is larger than or equal to 1, subtracts 2 from
this number. Test it, step-by-step, on the example of n = 2.
Solutions to Problem 15
16. (Due October 25) Design a Turing machine that, given a
binary number n, adds 4 to this number. Test it, step-by-step, on
the example of n = 1.
Solutions to Problem 16
17. (Due October 25) Use the general algorithm to transform
a finite automaton B from Homework 1.4 -- as simplified in Homework
3, into a Turing machine. Show step-by-step, on an example of a
word Aa0, how this word will be processed by your Turing
machine.
Solutions to Problem 17
18. (Due October 25) As described in the corresponding
lecture, every grammar obtained from a finite automaton is LL(1).
For the grammar from Homework 8, build the corresponding table.
Solutions to Problem 18
19. (Due November 1) Write a program that, given an
arithmetic expression,
- first transforms it to a postfix
form, and then
- computes its value (by using the stack-based
algorithms that we recalled in class).
You can assume that
the expression contains no variables, only numbers, and all the
numbers are one-digit numbers, i.e., each of these numbers is
either 0, or 1, or 2, ..., or 9. For example, your program should
correctly process expressions like 2+3*4, but there is no need to
process expressions like 11+22. For simplicity, assume that the
only arithmetic operations are addition +, subtraction −, and
multiplication *, and that there are no parentheses.
Comments:
- as with all programming assignments for
this class, submit a file containing the code, and a file
containing an example of what this program generates on each
step;
- ideally, use Java, but if you want to write it in some
other programming language, check with the TA that it is OK;
usually, C or C++ are OK.
20. (Due November 1) As we discussed in the corresponding
lecture, a Turing machine can be described as a finite automata
with two stacks:
- the right stack contains, on top, the
symbol to which the head points; below is the next symbol to the
right, then the next to next symbol to the right, etc.;
- the
left stack contains, on top, the symbol directly to the left of the
head (if there is a one), under it is the next symbol to the left,
etc.
On the example a Turing machine that computes n − 1
for a binary number n = 2, show, step-by-step: - how each
state of the corresponding Turing machine can be represented in
terms of two stacks, and
- how each transition from one state to
another can be implemented by push and pop operations.
Solutions to Problem 20
21. (Due November 8) Write and test a method that simulates
a general Turing machine. Your program should enable the computer
to simulate any given Turing machine for accepting-rejecting and
then to simulate, for any given word, step-by-step, how this Turing
machine decides whether this word is accepted or not.
The input to this method should include:
- the number N of
states q0, ..., qN − 1; we assume that
q0 is the start state, that the last-but-one state
qN − 2 is the accept state, and the last state
qN − 1 is the reject state;
- the number M of
symbols s0, ... sM − 1; we assume that
s0 is the blank state _;
- an integer array
state[n][m] that describes to what state the head of the Turing
machine changes if it was in the state qn and sees the
symbol sm;
- an integer array symbol[n][m] that
describes what symbol should be on the tape after the head in the
state qn sees the symbol sm (it may be the
same symbol as before, or it may be some other symbol written by
the Turing machine);
- a character array lr[n][m] that
describes, for each state qn and for each symbol
sm, whether the head moves to the left (L), or to the
right (R), or stays in place (blank symbol);
- the integer array
of a large size describing the original contents of the tape, i.e.,
what symbols are written in each cell.
This program needs to
keep track of a current location of the head. Initially, this
location is 0.
Your program should simulate the work of the Turing machine
step-by-step. Return the printout of the method, the printout of
the program that you used to test this method, and the printout of
the result of this testing. Feel free to use Java, C, C+++,
Fortran, or any programming language in which the code is
understandable.
22. (Due November 8) Give two examples:
- an example
of computation time which makes an algorithm feasible according to
the formal definition but not practically feasible, and
- an
example of computation time for which the corresponding algorithm
is practically feasible, but not feasible according to the formal
definition.
These examples should be different from what you
learned in class -- a minor difference is OK.
Solutions to Problem 22
23. (Due November 15) What is NP? What is P? What is
NP-complete? What is NP-hard? Give brief definitions. Give an
example of an NP-complete problem. Is P equal to NP?
Solutions to Problem 23
24. (Due December 6) Prove that the square root of 18 is not
a rational number.
Solutions to Problem 24