“When the term machine is used in ordinary discourse, it tends to evoke an unattractive picture. It brings to mind a big, heavy, complicated object which is noisy, greasy, and metallic; performs jerky repetitive, and monotonous motions; and has sharp edges that may hurt one if he does not maintain sufficient distance… Our concern is with questions about the ultimate theoretical capacities and limitations of machines [and so] it is necessary to abstract away many realistic details and features of mechanical systems…
We ignore, in our abstraction, the geometric or physical composition of mechanical parts. We ignore questions about energy. We even shred time into a sequence of separate, disconnected moments, and we totally ignore space itself! Can such a theory be a theory of any ‘thing’ at all? Incredibly, it can indeed.”
—Marvin Minsky, Computation: Finite and Infinite Machines
Our fundamental model of computation in this class will be the state machine.
A state machine is (a formal specification of) any system that can be in different states/configurations at different times, and which can change its state/configuration depending on external events (user input, time passing, etc.).
We say that a state machine is deterministic if, given the current state and an external event, there is a unique next state (determined by the current state and the specific event) of the system. More formally:
A Deterministic State Machine is a 5-tuple where
We say that a deterministic state machine accepts a string if following transitions (using ) starting from according to the successive letters of we end up in a state in .
More formally, accepts a string if is true, where the predicate is defined recursively as follows:
Given a state machine , its language is defined to be the set of all strings accepted by the machine, i.e.,
It follows that accepts iff .
A Deterministic Finite State Machine (DFSM), also known as a Deterministic Finite Automaton (DFA), is a deterministic state machine where the set of possible states is finite.
For small DFAs, it’s common to specify the components of the state machine visually:

This same DFA

abb, because the transitions take us from the
start state to to to , and is not an accepting
state.abc, because the transitions take us from to
to to , and is an accepting state.abca, because the transitions take us from to
to to to , and is not an accepting state.
This DFA accepts any string of 0’s and 1’s that contains an even number of 0’s (by using different states to keep track of whether it has seen an even number of 0’s so far, or an odd number of 0’s).

This DFA accepts any string of 0’s and 1’s that contains an even number of 0’s (by using different states to keep track of the three most-recently seen bits).
It can be useful to relax the requirement that our finite state machines be deterministic. A Nondeterministic Finite State Machine (NDFSM) or Nondeterministic Finite Automaton (NFA) allows a choice of possible next states for a given input, and it allows a change of state even in the absence of inputs. Further, given such a choice, an NFA can correctly “guess” which transition to take next!
Guessing is hard to implement directly, but we’ll see later that it’s possible to implement indirectly because any NFA can be simulated by a DFA (and hence, in principle, by a digital computer).
An NFA (Nondeterministic Finite Automaton) is a 5-tuple where
For small NFAs, it’s common to specify the components of the state machine visually:

An NFA accepts the string if it is possible to take transitions spelling out (plus optionally transitions labeled and get from the start state to some accepting state in .
The language of NFA is the set of strings accepted by .
This same NFA

accepts bb via the path , , .
Note: it doesn’t matter that there are
other paths spelling out bb that don’t accept, such as , , ; an NFA
accepts if at all possible, so as long as one accepting path exists, the
string is accepted!
accepts b via the path , (via ), , (via
again).
This path spells out , but that’s just the same string as , because a string doesn’t change when you append an empty string.
accepts aaab via the path , (via ), , ,
.
accepts ba via the path , (via ), , (via
again), .
does not accept aa because there is no path from to an
accepting state that involves two a transitions (even
allowing transitions).
NFAs can be much smaller than the equivalent DFA. To determine whether the third-to-last digit of a binary input is 1, the DFA above required eight states. An NFA can do the same job in four states:

This NFA stays until the start state until all but the last three bits have been read; if the third-to-last bit is a 1, it can then transition to an accept state.
If we wanted to know the fourth-to-last digit, a DFA would require 16 states, whereas an NFA would require only five. If we wanted the fifth-to-last digit, a DFA would require 32 states, whereas an NFA would require only six. In general, DFAs can be exponentially bigger than NFAs to do the same job.
Soon we will show that for any DFA there is a NFA with the same language, and vice-versa. But first, we need to define the notion of a Regular Language.